Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Подвисание при создании потока в хуке, ошибка 1444 - ERROR_INVALID_THREAD_ID 
V
    Опции темы
MetalFan
Дата 18.5.2009, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



Цитата(CodeMonkey @  18.5.2009,  13:43 Найти цитируемый пост)
А о том, что Resume в AfterConstruction вызывается - вы не подумали?

а что в этом плохого, если поток и так запущен?


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
CodeMonkey
Дата 18.5.2009, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



Цитата
а что в этом плохого, если поток и так запущен?

За исключением того, что мы городим кривой код на ровном месте - ничего ;)


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
MetalFan
Дата 18.5.2009, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



CodeMonkey, 
ну с одной стороны, делать Resume в конструкторе TThread нам ничего не мешает, но с другой - это нарушает идеология самого класса...


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
kami
Дата 18.5.2009, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(CodeMonkey @  18.5.2009,  13:43 Найти цитируемый пост)
А о том, что Resume в AfterConstruction вызывается - вы не подумали?

Подумал давно, и тогда же посмотрел.
Код

procedure TThread.AfterConstruction;
begin
  if not FCreateSuspended then // если создали не "спящим",
    Resume; // то пробуждаем.
// а если спящим (мой случай) - ничего не делаем.
end;

И зачем мне перекрывать еще и этот метод? Не вижу разницы в вызове Resume в AfterConstruction или в конструкторе после inherited.

Цитата(CodeMonkey @  18.5.2009,  13:43 Найти цитируемый пост)
Да даже, если просто тупо WaitForSingleObject - там "завис"-то будет в сотые доли секунды.

Вопрос:
а что ждать?
В конструкторе ничего не создается.
В процедуре потока - мьютекс, MMF и окно. Но! Они могут быть не-инициализированы даже после отработки AfterConstruction, ибо кто кроме планировщика потоков Windows может знать, когда управление в первый раз будет отдано в этот новый поток?
Цитата(CodeMonkey @  18.5.2009,  13:43 Найти цитируемый пост)
Тогда проверяйте свой код - должен работать.

Теперь, с учетом 
Цитата(MetalFan @  17.5.2009,  16:11 Найти цитируемый пост)
не рекомендуется делать лишние телодвижения (в т.ч. создавать потоки) в DllMain при загрузке библиотеки...

работает. Правда, одно лишнее телодвижение осталось - создание потока. Вот только без ожидания его инициализации. Потокобезопасные процедуры работы с ним позволяют безболезненно обойти это, за исключением 2-х моментов:
1. поток создан, но данные в execute не инициализированы. В этом случае утечек нет.
2. Поток жестко терминирован. Утечки будут. Малого размера, но будут.
PM MAIL WWW   Вверх
MetalFan
Дата 18.5.2009, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



Цитата(kami @  18.5.2009,  18:42 Найти цитируемый пост)
Малого размера, но будут. 

тебя это, похоже, не должно беспокоить...

Цитата(kami @  17.5.2009,  21:55 Найти цитируемый пост)
Совершенно верно.
PostMessage(msgAddData, integer(pData), DataSize);
Поток будет терминирован, если:
1. Завершено приложение, в которое внедрен хук.
2. Вызывано UnHookWindowsHookEx для всех установленных из dll хуков.

И в том и в другом случае приходящие после этого данные уже не актуальны. 

т.е. необработанное сообщение приведет опять же к небольшой утечке памяти.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
kami
Дата 18.5.2009, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(MetalFan @  18.5.2009,  20:27 Найти цитируемый пост)
тебя это, похоже, не должно беспокоить

Да.
Я не думаю, что утечка в 2*SizeOf(integer) - большая проблема для чужого приложения. Даже случившаяся несколько раз.
Цитата

Вызывано UnHookWindowsHookEx для всех установленных из dll хуков.

Небольшая поправка:
вызов UnHookWindowsHookEx не приведет к моментальной выгрузке dll из адресного пространства всех процессов, но хуки уже вызываться не будут.
PM MAIL WWW   Вверх
CodeMonkey
Дата 18.5.2009, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



Цитата(kami @  18.5.2009,  21:46 Найти цитируемый пост)
Я не думаю, что утечка в 2*SizeOf(integer) - большая проблема для чужого приложения

На сервере подкачка = смерти ;)


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
kami
Дата 18.5.2009, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(CodeMonkey @  18.5.2009,  23:30 Найти цитируемый пост)
На сервере подкачка = смерти ;)

/me тяжко вздыхает.
Знаю. Читал. Стараюсь свести к минимуму.
Но синхронизацию при добавлении данных использовать не могу. В данном случае.

В любом случае - огромное спасибо MetalFan и CodeMonkey за помощь.
Без вас наверное, до сих пор зависал бы на конструкторе потока, пытаясь понять отчего же он не работает.

Кстати, это может объяснить и неработоспособность компонентов-оберток над namedPipes, которые и послужили началом разбирательства на предыдущую и эту темы.
PM MAIL WWW   Вверх
dumb
Дата 19.5.2009, 02:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 7
Всего: 158



kami, я правильно понимаю: избегая "блокировки" на "ожидании" мьютекса, ты создаешь поток, чтобы "быстро" туда постить инфу?
тогда тебе удалось сделать из мухи здоровенного такого африканского слона. smile

если между захватом мьютекса(WaitForSingleObject) и его освобождением(ReleaseMutex) будут только элементарные операции копирования кусков памяти, то функция ожидания(WaitForSingleObject) в подавляющем большинстве случаев будет встречать свободный мьютекс и выполняться без какой-либо задержки.

если же брать в расчет доп.затраты на обслуживание созданных тобой потоков(в количестве равном числу gui-процессов), то суммарное время, затрачиваемое на обработку, будет больше в разы.

Цитата(kami @  18.5.2009,  23:41 Найти цитируемый пост)
Но синхронизацию при добавлении данных использовать не могу. В данном случае.
сдается, что в данном случае такая категоричность безосновательна.

"Premature optimization is the root of all evil" (с)

PM MAIL   Вверх
CodeMonkey
Дата 19.5.2009, 08:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



Мне тоже кажется, что вы что-то не то делаете, но мне как-то лень копаться  smile 
В общем случае надо бы убрать всё из DllMain, все вещи инициализировать по первому обращению, а глобальные ресурсы хранить в глоб. переменных/threadvar/списке и удалять при выгрузке DLL. Плюс предусмотреть ситуацию переустановки хука без выгрузки DLL.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
kami
Дата 19.5.2009, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(dumb @  19.5.2009,  02:48 Найти цитируемый пост)
 избегая "блокировки" на "ожидании" мьютекса, ты создаешь поток, чтобы "быстро" туда постить инфу?

Нет, этого я  не избегаю.
Работа доп.потока организована в строгом соответствии с Вашими рекомендациями в предыдущей ветке.
А вот добавление данных из другого потока сделано как PostMessage(hwnd, msgAddData, integer(@Data), DataSize);

Цитата(dumb @  19.5.2009,  02:48 Найти цитируемый пост)
если между захватом мьютекса(WaitForSingleObject) и его освобождением(ReleaseMutex) будут только элементарные операции копирования кусков памяти,

Именно так.

Цитата(CodeMonkey @  19.5.2009,  08:37 Найти цитируемый пост)
Мне тоже кажется, что вы что-то не то делаете

Спорить не буду, т.к. учусь, в основном - на своих ошибках smile.
Цитата(CodeMonkey @  19.5.2009,  08:37 Найти цитируемый пост)
но мне как-то лень копаться

Согласен, чужой код, как и душа - потемки.

Цитата(CodeMonkey @  19.5.2009,  08:37 Найти цитируемый пост)
В общем случае надо бы убрать всё из DllMain

Уже думал, попробую и этот вариант.
Цитата(CodeMonkey @  19.5.2009,  08:37 Найти цитируемый пост)
Плюс предусмотреть ситуацию переустановки хука без выгрузки DLL.

Ага, для меня сейчас это самое узкое место.

PM MAIL WWW   Вверх
CodeMonkey
Дата 19.5.2009, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



Цитата
Ага, для меня сейчас это самое узкое место.

Как-то так:

DLL:
Код
var
  SavedHandle: THandle;
  GlobalData: PSomeStruct;  

  Threads: array of TThread; // и т.п.

procedure HookHandler(...);
begin
  if Assigned(GlobalData) and (GlobalData^.Handle <> SavedHandle) then
  begin
    DeleteHookData; // + стоп всего
    SavedHandle := 0; // внутри DeleteHookData
  end;
  if GlobalData = nil then
  begin
    CreateHookData; // + старт всего
    SavedHandle := GlobalData^.Handle; // внутри CreateHookData
  end;

  // работа хука
end;

// DllProc:
begin
  // при process detach:
  DeleteHookData; // + стоп всего
  SavedHandle := 0; // внутри DeleteHookData
end;


App:
Код
var
  GlobalData: PSomeStruct;  

  CreateHookData;
  GlobalData^.Handle := // любое значение, уникально идентифицирующее хук. Например, ровно описатель хука от SetWindowsHookEx
...
  GlobalData^.Handle := 0;
  DeleteHookData;


Добавлено через 3 минуты и 8 секунд
Немного непонятно, на что конкретно ставиться хук. В принципе, если хук, скажем, на GetMessage, то вместо DeleteHookData при process detach можно делать broadcast сообщения, по которому отцепляется DeleteHookData. Ну и в DLLProc вызов всё же оставить - на всякий пожарный.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
dumb
Дата 19.5.2009, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 7
Всего: 158



народ, не настаиваю, но может таки на "ты"? - общение все же не официальное.

Цитата(kami @  19.5.2009,  13:06 Найти цитируемый пост)
Нет, этого я  не избегаю.
для чего тогда вообще создается доп.поток в контексте чужого процесса? - из обработчика хука сразу класть в mmf структуру.

Цитата(kami @  19.5.2009,  13:06 Найти цитируемый пост)
Работа доп.потока организована в строгом соответствии с Вашими рекомендациями в предыдущей ветке.
эм. я насчет доп.потока ничего не говорил. сейчас, исходя из того, что вижу в коде hlibstaex, еще раз скажу: не нужен доп.поток.
PM MAIL   Вверх
kami
Дата 19.5.2009, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(dumb @  19.5.2009,  16:02 Найти цитируемый пост)
народ, не настаиваю, но может таки на "ты"? - общение все же не официальное.

Согласен, просто привык обращаться уважительно к людям, которые могут что-то подсказать/посоветовать.

Цитата(dumb @  19.5.2009,  16:02 Найти цитируемый пост)
исходя из того, что вижу в коде hlibstaex, еще раз скажу: не нужен доп.поток.

Ок, переделать из потока в обычный класс, обслуживающий mmf - небольшая проблема. Попробую.

Вах!
Цитата(dumb @  19.5.2009,  16:02 Найти цитируемый пост)
исходя из того, что вижу в коде hlibstaex, 

а это как?
Присоединённый файл ( Кол-во скачиваний: 1 ) - это ж я скачивал, чтобы проверить работоспособность ссылки  smile  smile 

Цитата(CodeMonkey @  19.5.2009,  14:14 Найти цитируемый пост)
Как-то так:

Примерно так и думал.
Единственное - до этого времени не держал открытой GlobalData.
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0723 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.