summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDyami Caliri <dyami@dragonframe.com>2014-04-30 09:36:53 -0700
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-05-23 16:20:07 +0200
commite9104b9a4a1c869050493181933c95cd2867a5e7 (patch)
tree2e16bf0d32f81e42b7010ecce8dfd518afbc38ea
parentd39e916c6f397801ac329968515d90f0d1b9ef8f (diff)
downloadqtserialport-e9104b9a4a1c869050493181933c95cd2867a5e7.tar.gz
Inspect lock file to determine busy state.
QSPI was relying on QLockFile.isLocked() to determine if the port was in use. This was due to a misunderstanding of the QLockFile class design. Ideally the code in QSPI.isBusy() should be moved into a new method, QLockFile.available(), since it contains implementation details of that class. Note that isBusy() is for information purposes only, since checking for a lock without obtaining it is always racy. Change-Id: I675bd4033e4228e6bf864bf2e7a00a2520ccc50e Reviewed-by: Sergey Belyashov <Sergey.Belyashov@gmail.com> Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r--src/serialport/qserialport_unix.cpp14
-rw-r--r--src/serialport/qserialportinfo_unix.cpp22
2 files changed, 24 insertions, 12 deletions
diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp
index a00d0db..1ba23dd 100644
--- a/src/serialport/qserialport_unix.cpp
+++ b/src/serialport/qserialport_unix.cpp
@@ -199,9 +199,8 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
}
QScopedPointer<QLockFile> newLockFileScopedPointer(new QLockFile(lockFilePath));
- lockFileScopedPointer.swap(newLockFileScopedPointer);
- if (lockFileScopedPointer->isLocked()) {
+ if (!newLockFileScopedPointer->tryLock()) {
q->setError(QSerialPort::PermissionError);
return false;
}
@@ -227,12 +226,6 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
return false;
}
- lockFileScopedPointer->lock();
- if (!lockFileScopedPointer->isLocked()) {
- q->setError(QSerialPort::PermissionError);
- return false;
- }
-
#ifdef TIOCEXCL
if (::ioctl(descriptor, TIOCEXCL) == -1)
q->setError(decodeSystemError());
@@ -268,6 +261,8 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
if ((flags & O_WRONLY) == 0)
setReadNotificationEnabled(true);
+ lockFileScopedPointer.swap(newLockFileScopedPointer);
+
return true;
}
@@ -306,8 +301,7 @@ void QSerialPortPrivate::close()
if (qt_safe_close(descriptor) == -1)
q->setError(decodeSystemError());
- if (lockFileScopedPointer->isLocked())
- lockFileScopedPointer->unlock();
+ lockFileScopedPointer.reset(0);
descriptor = -1;
pendingBytesWritten = 0;
diff --git a/src/serialport/qserialportinfo_unix.cpp b/src/serialport/qserialportinfo_unix.cpp
index 3440ad2..783105e 100644
--- a/src/serialport/qserialportinfo_unix.cpp
+++ b/src/serialport/qserialportinfo_unix.cpp
@@ -50,6 +50,11 @@
#include <QtCore/qdir.h>
#include <QtCore/qscopedpointer.h>
+
+#include <errno.h>
+#include <sys/types.h> // kill
+#include <signal.h> // kill
+
#ifndef Q_OS_MAC
#include "qtudev_p.h"
@@ -344,8 +349,21 @@ bool QSerialPortInfo::isBusy() const
if (lockFilePath.isEmpty())
return false;
- QLockFile lockFile(lockFilePath);
- return lockFile.isLocked();
+ QFile reader(lockFilePath);
+ if (!reader.open(QIODevice::ReadOnly))
+ return false;
+
+ QByteArray pidLine = reader.readLine();
+ pidLine.chop(1);
+ if (pidLine.isEmpty())
+ return false;
+
+ qint64 pid = pidLine.toLongLong();
+
+ if (pid && (::kill(pid, 0) == -1) && (errno == ESRCH))
+ return false; // PID doesn't exist anymore
+
+ return true;
}
bool QSerialPortInfo::isValid() const