/* * Unofficial Qt Serial Port Library * * Copyright (c) 2010 Inbiza Systems Inc. All rights reserved. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see * * author labs@inbiza.com */ #include #include #include #include #include "commdcbhelper.h" #include "wincommevtbreaker.h" namespace TNX { TimeKeeper::TimeKeeper(WinCommEvtBreaker *owner, QMutex &mutex, QObject *parent) : QObject(parent), mutex_(mutex) { if ( !owner ) return; qRegisterMetaType("HANDLE"); connect(owner, SIGNAL(startTimer(HANDLE, int)), SLOT(startWaitTimer(HANDLE, int)), Qt::BlockingQueuedConnection); connect(owner, SIGNAL(stopTimer(HANDLE)), SLOT(stopWaitTimer(HANDLE)), Qt::BlockingQueuedConnection); } /** * */ void TimeKeeper::timerEvent(QTimerEvent *event) { QMutexLocker locker(&mutex_); killTimer(event->timerId()); if ( !handleList_.contains(event->timerId()) ) return; HANDLE commHandle = handleList_.take(event->timerId()); // force WaitCommEvent() to exit from blocked-wait by setting different event mask DWORD allFlags = EV_RXCHAR | EV_TXEMPTY | EV_CTS | EV_DSR | EV_RLSD | EV_BREAK | EV_ERR | EV_RING | EV_PERR | EV_RX80FULL | EV_EVENT1 | EV_EVENT2; if ( !SetCommMask(commHandle, allFlags) ) { qDebug() << QString("TimeKeeper::timerEvent(hnd: %1) failed when resetting comm event mask: %2(Err #%3)") .arg((int)commHandle) .arg(CommDCBHelper::errorText(GetLastError())) .arg(GetLastError()); } } void TimeKeeper::startWaitTimer(HANDLE commHnd, int timeout) { QMutexLocker locker(&mutex_); int timerId = startTimer(timeout); handleList_.insert(timerId, commHnd); } void TimeKeeper::stopWaitTimer(HANDLE commHnd) { QMutexLocker locker(&mutex_); QList timerIdList = handleList_.keys(commHnd); foreach (int timerId, timerIdList) { killTimer(timerId); handleList_.remove(timerId); } } /** * */ void WinCommEvtBreaker::run() { // store this thread's id threadId_ = QThread::currentThreadId(); timeKeeper_ = new TimeKeeper(this, mutex_); // as owner, not as parent Q_CHECK_PTR(timeKeeper_); exec(); delete timeKeeper_; } void WinCommEvtBreaker::startWaitTimer(HANDLE commHnd, int timeout) { emit startTimer(commHnd, timeout); } void WinCommEvtBreaker::stopWaitTimer(HANDLE commHnd) { emit stopTimer(commHnd); } } // namespace