Цитата
Могу подключиться только после перезапуска проги (или если удалить из /var/lock, но не пробовал ещё). Так что косяк иногда существенный, приходится прогу перезапускать, чего нехотелось бы. Поправимо ли это?
В принципе всё поправимо. Пройдитесь дебаггером в момент закрытияи и посмотрите где оно косячит.
В принципе я догадываюсь в чем дело:
--------------------------------------
Суть в том, что за lock/unlock отвечает класс TTYLocker. В него передается имя порта для того, чтобы класс создавал соответствующие ему лок файлы в виде major/minor и имени (т.е. "/LCK.%1.%2" и /LCK..%1), т.е. создается сразу два лок-файла.
Для определения major/minor номера устройства используется POSIX функция stat(...) которая принимает два параметра :
один - имя устройства
второй - буфер куда будет записан major/minor.
Так вот, когда мы открыли порт
open(), после этого вызывается метод
TTYLocker::lock() , который создает два лок файла в которые записывает некоторые параметры.
Теперь мы закрываем порт
close(), после этого вызывается метод
TTYLocker::unlock(), который удаляет два лок-файла.
Но всё дело в том, что для получения имен лок-файлов, класс TTYLocker использует только имя самого порта!
Т.е. за это отвечают методы:
QString TTYLocker::getLockFileInNumericForm() const
QString TTYLocker::getLockFileInNamedForm() const
Теперь, если мы вызвали метод
close(), и при этом, порт присутствует в системе, то метод
QString TTYLocker::getLockFileInNumericForm() const
вернет корректное имя лок-файла и удалит его.
НО в случае, когда мы выдернули шнурок, то порт из системы пропал, следовательно метод
QString TTYLocker::getLockFileInNumericForm() const
вернет пустое имя лок-файла, т.к. самого устройства в системе уже нет, и определить его major/minor не представляется возможным.
В данной ситуации TTYLocker удалит только один лок-файл (из двух), связанный только с именем порта, а лок-файл, связанный с major/minor останется в системе.
Теперь, мы вставляем снова шнурок и пытаемся открыть порт.. НО, класс TTYLocker видит, что уже есть лок-файл с major/minor этого порта и PID (идентификатор процесса использующего порт) равен PID-у нашего приложения, а также этот PID активен!
Поэтому TTYLocker "делает вывод" что порт уже занят!
Поэтому если мы перезапустим приложение, то TTYLocker увидит этот же лок-файл, но в нём PID уже не будет равен PID-у нашего приложения.
Поэтому TTYLocker "делает вывод" что порт свободен!
--------------------------------------
Вот вкратце чисто гипотетическое предположение что происходит.
Я пока не решил еще, правильный ли алгоритм у TTYLocker или нет. Но, хочу заметить, что я "передирал" реализацию TTYLocker из других опен сурц проектов, поэтому не думаю, что она некорректна (хотя ХЗ).
Т.е. временное решение - это в коде TTYLocker закомментировать вообще всё что связано с лок-файлом по major/minor, т.е. в итоге нужно чтобы будет создавался один лок-файл связанный только с именем устройства.
Я пока не буду трогать код, но вы для себя можете это сделать.