Sunday 15 July 2012

c++ - preventing deadlocks when using sockets -



c++ - preventing deadlocks when using sockets -

i working on server(i'm using qt g.u.i. framework)/client application in c++ first time, , have stumbled upon rather annoying issue.

first off, allow me give details:

i on windows 10 x64 i'm using visual studio ide & qt g.u.i. signal/slots used needed connected. new multi-threading concepts. self-taught, don't know much concepts called.

basic outline:

i working on file uploader. file uploader, have 2 classes, 1 thread communicates client(let's phone call classa) & other qobject form(let's phone call classb). when user closes form triggers closeevent() in classb sets 'bdead' variable in classa(it uses qmutex create sure other thread isn't accessing it, suppose it's thread-safe). 1 time client thread notices alter in classa, finishes it's work & sets bverifieddead in classb true can both free without worry of beingness accessed when destroyed.

for form:

#include "uploadselect.h" uploadselect::uploadselect(qwidget *parent) : qwidget(parent) { ui.setupui(this); bclosedbyuser = true; bverifieddead = false; bdead = null; } /* bool uploadselect::verifydeath() { bool bresult; mutex.lock(); bresult = bverifieddead; mutex.unlock(); homecoming bresult; } */ void uploadselect::close() { bclosedbyuser = false; close(); } void uploadselect::closeevent(qcloseevent *event) { if (bclosedbyuser) { mutex.lock(); *bdead = true; mutex.unlock(); while (true) { mutex.lock(); if (bverifieddead) { mutex.unlock(); break; } mutex.unlock(); sleep(250); } } delete this; }

uploadselect.h:

#pragma 1 time #ifndef win32_lean_and_mean #define win32_lean_and_mean #endif #include <winsock2.h> #include <windows.h> #include <qwidget> #include <qdialog> #include "ui_uploadselect.h" class uploadselect : public qwidget { q_object public: uploadselect(qwidget *parent = 0); ~uploadselect(){}; qmutex mutex; bool bclosedbyuser, *bdead, bverifieddead; public slots: void close(); private: ui::uploadselect ui; protected: void closeevent(qcloseevent *event); };

uploadselectthrd.h:

#pragma 1 time #include <qthread> #include <qsystemtrayicon.h> #include <qtreewidget.h> class uploadselect; class uploaderselectthread : public qthread{ q_object public: uploaderselectthread(qobject* parent = 0){ bformdead = false; }; ~uploaderselectthread(){}; void run(); bool bformdead; uploadselect* ui; private: bool formdying(); signals: void close(); };

uploadselectthrd.cpp:

#ifndef win32_lean_and_mean #define win32_lean_and_mean #endif #ifndef nominmax //error c2589: '(' : illegal token on right side of '::' c:\qt\5.3\msvc2013_64\include\qtcore\qdatetime.h occur if not defined before windows.h/winsock2.h(winsock2 includes windows.h) #define nominmax #endif #include <winsock2.h> #include <windows.h> #include <qmutex.h> #include "filelist.h" #include "uploadselecthrd.h" #include "uploadselect.h" #include "../stub/sockutils.h" using namespace sockwrapper; bool uploaderselectthread::formdying() { bool bresult; ui->mutex.lock(); bresult = bformdead; ui->mutex.unlock(); homecoming bresult; } void uploaderselectthread::run() { connect(this, signal(finished()), this, slot(deletelater())); //socketwrapper* client = new socketwrapper(ssock); int = 0; while (i < 6 && formdying() == false) { sleep(1000); i++; } if (!formdying()) { outputdebugstringa("\r\n\r\n\r\n\r\nbformdead == false"); emit close(); } else { ui->mutex.lock(); ui->bverifieddead = true; ui->mutex.unlock(); outputdebugstringa("\r\n\r\n\r\n\r\nbformdead == true"); } }

the way i've coded things; sockets synchronous let's suppose client's connection isn't , takes ~10 seconds before send function returns , allows client check variable.

this cause 10 sec deadlock, sucks...

it's incomplete because previous project got messed up(so started new 1 i'm slowing re-coding into).

possible solutions i've thought of:

instead of deleting classb in closeevent(), set variable in classa in thread classa take care of when it's finished.

c++ qt sockets

No comments:

Post a Comment