Notes |
|
|
У меня на 4-х ядерном проце выдает ошибку при закрытии и без включенного центрирования. А вот на стареньком P4 никаких проблем не наблюдается. |
|
|
|
>на 4-х ядерном проце выдает ошибку при закрытии и без включенного центрирования
На CloseHandle (оно же NtClose) для thread?
А то у меня даже мыслей нету ((( |
|
|
|
>На CloseHandle (оно же NtClose) для thread?
Вроде бы да. Сейчас проверить не могу. Причем стек именно такой как в приаттаченном файле. |
|
|
|
Ну ты блин даешь. Сначала создаешь тред с параметром
FPacketThread.FreeOnTerminate:=TRUE;
А потом пытаешься его убить в деструкторе
FreeAndNil(FPacketThread); |
|
|
|
Да и вообще, использование указателя на тред после того как поставил ему FreeOnTerminate:=TRUE;
это отличный способ стрельбы по своим ногам :) |
|
|
|
FPacketThread.OnTerminate:=InternalOnPacketThreadTerminate;
внутри обработчика FPacketThread должно подчищаться как бы. |
|
|
|
Ну и что. Вот ты получил ссылку на тред из переменной FPacketThread. Она скопировалась в стек. Проверилась. Не нулевая. В это время тред завершил работу и вызвал OnTerminate. Переменная FPacketThread обнилилась, но на стеке то лежит ненулевая ссылка. Вот в ней то деструктор второй раз и вызывается. |
|
|
|
Золотое правило. Если ты поставил FreeOnTerminate:=TRUE то забудь о существовании ссылки на этот объект. Она в любой момент может стать невалидной. |
|
|
(0008211)
|
vasketsov
|
07-08-2012 13:01
(edited on: 07-08-2012 13:06) |
|
Здесь это "золотое правило" не всегда применимо. Если поток завис, то Terminate его ничего не даст. А убить его надо, так что остаётся только "хэдшот в ногу" ))).
Если ты прав в этом конкретном случае, то обрамление обNILивания и FreeAndNil в критическую секцию решит проблему. Но у меня проблемы с воспроизведением этого.
А сбрасывать FreeOnTerminate тут нельзя, так как при отключении GPS (по кнопке на панели инструментов) просто испускается Terminate и не ждётся Free.
|
|
|
|
Добавь критическую секцию, а я проверю. У меня дома на 4-х ядернике воспроизводится на ура. |
|
|
|
Критическая секция там уже есть, её надо только подключить.
Сейчас приаттачу EXE с захватом секции.
Если захочешь поиграться самостоятельно - в файле RUNTIME/vsagps_object.pas
надо сделать
- FreeAndNil(FPacketThread);
+ EnterCriticalSection(FCS_CloseHandle);
+ try
+ FreeAndNil(FPacketThread);
+ finally
+ LeaveCriticalSection(FCS_CloseHandle);
+ end;
и внутри InternalOnPacketThreadTerminate соответственно
- FPacketThread:=nil;
+ EnterCriticalSection(FCS_CloseHandle);
+ try
+ FPacketThread:=nil;
+ finally
+ LeaveCriticalSection(FCS_CloseHandle);
+ end; |
|
|
|
Совсем другое дело. Можно коммитить в репо и закрывать баг. |
|
|
|
Закоммитил. Приаттаченный EXE удалил. |
|