Поток возвращается на неверный адрес

У меня странная проблема с использованием потоков внутри плагина Firebreath (в данном случае плагина FB, но это может произойти где угодно); попробую объяснить:

  • 1) Мой плагин создает поток (статический) и получает указатель на «это» каждый раз, когда он добавляется на страницу.
  • 2) Итак, теперь у меня есть поток с указателем на плагин, поэтому я могу вызывать его методы.
  • 3) Пока очень красиво, НО, предположим, что у меня есть кнопка (закодированная в HTML), которая при нажатии будет УДАЛИТЬ текущий плагин, поставить на место другой и запустить другой поток.

Я описал свой сценарий, теперь о проблеме, когда добавляется плагин, он запускает поток; внутри потока есть указатель на "это". В первый раз он запускается... пока поток выполняется, я нажимаю кнопку HTML (таким образом, текущий плагин теперь уничтожен) и размещается новый. Поток из 1-го плагина завершается и теперь возвращается... но он возвращается ко 2-му экземпляру плагина.

Плагин является просмотрщиком изображений, первый плагин ищет картинку, она удаляется и ставится новая; НО изображение из 1-го плагина помещается во 2-й. Я не знаю, с чего начать поиск, видимо, указатель имеет адрес плагина (например, 12345), плагин удаляется и создается снова с тем же адресом памяти (12345).

Есть ли способ избежать такого поведения?

Это код, который у меня есть до сих пор:

мой плагин.h

unsigned ThreadId; 
HANDLE hThread;

myPlugin.cpp

unsigned __stdcall myPlugin::Thread(void *data)
{  
        myPlugin* this = (myPlugin*) data; 
        this->getImage("http:\\host.com\\image.jpg");  
    _endthreadex(0); //EDIT: addedd this missing line to end the thread
}
void myPlugin::onPluginReady(std::string imageUrl) 
{  
    hThread = (HANDLE)_beginthreadex(NULL, 0, myPlugin::Thread, (void*) **this**, 0, &ThreadId); 
}
void myPlugin::getImage() 
{  
    //get an image using CURL... //no problem here 
}

person Maximiliano Santa Cruz    schedule 06.03.2012    source источник
comment
Где код, который завершает поток? Должно быть какое-то место, где вы 1. Попросите закончить нить. 2. дождаться окончания. 3. выгрузить плагин.   -  person nos    schedule 07.03.2012
comment
Добавлено _endthreadex(0); в функцию Thread. Спасибо.   -  person Maximiliano Santa Cruz    schedule 07.03.2012
comment
Да, так это делается. Что касается упомянутых вами шагов; 1) можно ли запросить завершение потока из-за пределов процесса потока? 2) Если я подожду, пока он закончится, у меня будет задержка; не так ли? 3) Процесс выгрузки запускается браузером   -  person Maximiliano Santa Cruz    schedule 07.03.2012


Ответы (1)


Вам нужно остановить и присоединиться к потоку в функции shutdown() вашего класса Plugin; который будет вызываться до того, как все будет фактически выгружено, и это поможет избежать проблемы.

Я бы также рекомендовал использовать boost::thread, так как FireBreath уже компилирует все это, и это поможет упростить некоторые из них; вы можете удерживать weak_ptr в своем потоке для класса плагина, а не передавать void*. Конечно, в любом случае вам нужно будет остановиться и присоединиться к потоку во время закрытия плагина (и поток должен быть остановлен быстро, иначе браузер будет раздражаться из-за того, что он занимает так много времени).

person taxilian    schedule 07.03.2012