Results 1 to 4 of 4

Thread: QMutex is not working in release mode

  1. #1
    Join Date
    Jan 2006
    Posts
    70
    Thanks
    13
    Thanked 5 Times in 5 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default QMutex is not working in release mode

    Qt 4.2.2 and MSVC 2003

    I have a class that inherits QThread with a buffer, QMutex, and QWaitCondition for data members.

    The run function of the thread does a mutex.lock() and then sends whatever is in the buffer over TCP and then does a wcond.wait(&mutex).

    Then whenever the classes event function receives an event it does a mutex.lock() fills the buffer and calls mutex.unlock() wcond.wakeall().

    This works great in debug mode, but not in release mode.

    I seem to have narrowed it down to whether the system linking option is on console or window. When on console the application works as expected. When you turn off the console by selecting window, the application seems to ignore the QMutex in that if the run function is sending the buffer the event will overwrite the buffer at the same time like they both have the mutex.

    I've tried with and without optimization but it's all dependent on that linker system option.

    Let me know if you need more information in order to guide me in the right direction. Thanks.

  2. #2
    Join Date
    Jan 2006
    Location
    Norway
    Posts
    124
    Thanked 38 Times in 30 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QMutex is not working in release mode

    The order of the calls is important. Especially releasing the mutex before waking the wait condition - if other things happen in the mean time you could end up in trouble.

    The difference in release and debug mode could just be a sign that you've got a race condition. QMutex's behavior is the same in debug and release mode.

    Could you post some sample code?
    Bitto / Andreas Aardal Hanssen - andreas dot aardal dot hanssen at nokia
    Nokia Software Manager, Qt Development

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QMutex is not working in release mode

    I guess it could help to swap the order of unlock() and wakeAll(), but as Andreas said, seeing the complete code of the section would help.

  4. #4
    Join Date
    Jan 2006
    Posts
    70
    Thanks
    13
    Thanked 5 Times in 5 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QMutex is not working in release mode

    Qt Code:
    1. #include <QtGui>
    2. #include <iostream>
    3. #include "controlThread.h"
    4. #include "controlEvent.h"
    5.  
    6. QMutex mutex;
    7.  
    8. using namespace std;
    9.  
    10. ControlThread::ControlThread(QObject* parent)
    11. : QThread(parent),
    12. _quit(false),
    13. _sendLen(0),
    14. _connected(false)
    15. {
    16. for (int i=0; i<MAX_SEND_BUFS; ++i)
    17. _sendBuf[i] = new char[64];
    18. }
    19.  
    20. ControlThread::~ControlThread()
    21. {
    22. for (int i=0; i<MAX_SEND_BUFS; ++i)
    23. delete [] _sendBuf[i];
    24.  
    25. _quit = true;
    26. cond.wakeAll();
    27. wait();
    28. }
    29.  
    30. void ControlThread::establishConnection()
    31. {
    32. mutex.lock();
    33. _connected = false;
    34. mutex.unlock();
    35.  
    36. printf("Control Thread: connection attempt\n");
    37. emit sigDataConnected(false);
    38.  
    39. // clean up socket descriptor before reconnect
    40. if (_socketFD)
    41. {
    42. perror("Conrol Thread: warning: socket deletion\n");
    43. closesocket(_socketFD);
    44. }
    45.  
    46. // create socket
    47. while ((_socketFD = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
    48. == INVALID_SOCKET)
    49. {
    50. perror("Control Thread: error: socket creation error\n");
    51. msleep(500);
    52. continue;
    53. }
    54.  
    55. // connect socket
    56. while ((::connect(_socketFD, (struct sockaddr*) &_tcpAddr,
    57. sizeof(struct sockaddr))) == SOCKET_ERROR &&
    58. (WSAGetLastError() != WSAEISCONN))
    59. {
    60. perror("Control Thread: error: connection timed out\n");
    61. msleep(500);
    62. continue;
    63. }
    64.  
    65. printf("Control Thread: connection successful\n");
    66.  
    67. mutex.lock();
    68. _connected = true;
    69. mutex.unlock();
    70. }
    71.  
    72. void ControlThread::run()
    73. {
    74. // init socket lib
    75. _socketFD = 0;
    76. WSADATA wsaData;
    77. while ((WSAStartup(MAKEWORD(1, 1), &wsaData)) != 0)
    78. {
    79. perror("Control Thread: error: socket lib init failed\n");
    80. msleep(100);
    81. }
    82.  
    83. _tcpAddr.sin_family = AF_INET;
    84. _tcpAddr.sin_port = ::htons(CONTROL_PORT);
    85. _tcpAddr.sin_addr.s_addr = ::htonl(CONTROLLER_IP);
    86.  
    87. establishConnection();
    88.  
    89. // create timeout variable
    90. timeval tv;
    91. tv.tv_sec = 0;
    92. tv.tv_usec = 200000;
    93. mutex.lock();
    94.  
    95. while (!_quit)
    96. {
    97. // send the commands and verify
    98. for (int i=0; i<_sendLen; ++i)
    99. {
    100. if ((sendToSocket(_sendBufLen[i], _sendBuf[i])) == 1)
    101. {
    102. perror("Control Thread: error: failed to send\n");
    103. mutex.unlock();
    104. establishConnection();
    105. mutex.lock();
    106. }
    107. }
    108.  
    109. cond.wait(&mutex);
    110. }
    111.  
    112. // cleanup
    113. closesocket(_socketFD);
    114. WSACleanup();
    115. }
    116.  
    117. int ControlThread::sendToSocket(int len, char *buf)
    118. {
    119. int s = 0;
    120. if (len > 0 && len != (s = ::send(_socketFD, buf, len, 0)))
    121. return 1;
    122. return 0;
    123. }
    124.  
    125. bool ControlThread::event(QEvent* evt)
    126. {
    127. if (evt->type() == (QEvent::Type) CONTROLID)
    128. {
    129. ControlEvent* cte = static_cast<ControlEvent*>(evt);
    130. bool keepTrying = true;
    131.  
    132. QMutexLocker m(&mutex);
    133.  
    134. _sendLen = 0;
    135. char* tmp = 0;
    136.  
    137. // check for position update
    138. float pos[3] = {0.0f, 0.0f, 0.0f};
    139. if (cte->getPositions(pos[0], pos[1], pos[2]))
    140. {
    141. _sendBufLen[_sendLen] = 0;
    142. cout << "Position ";
    143. tmp = _stream.PackData(AEZ, sizeof(float)*3, pos,_sendBufLen[_sendLen]);
    144. memcpy(_sendBuf[_sendLen], tmp, _sendBufLen[_sendLen]);
    145. _sendLen++;
    146. }
    147.  
    148. // check for timing dialog updates
    149. unsigned char timingCode[32];
    150. unsigned int timingVal[32];
    151. int len = 0;
    152. if (cte->getTimingUpdate(timingCode, timingVal, len))
    153. {
    154. cout << "timing update";
    155. for (int i=0; i<len; ++i)
    156. {
    157. _sendBufLen[_sendLen] = 0;
    158. tmp = _stream.PackData(timingCode[i], 4, timingVal+i, _sendBufLen[_sendLen]);
    159. memcpy(_sendBuf[_sendLen], tmp, _sendBufLen[_sendLen]);
    160. _sendLen++;
    161. }
    162. }
    163.  
    164. cout << " sent\n";
    165.  
    166. if (!isRunning())
    167. start();
    168. else
    169. cond.wakeAll();
    170.  
    171. // accept this event
    172. evt->accept();
    173. return true;
    174. }
    175. return QThread::event(evt);
    176. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Difference between Debug and Release Mode
    By sunil.thaha in forum Qt Programming
    Replies: 2
    Last Post: 5th May 2013, 13:31
  2. qodbc driver not loaded error in release mode
    By mandal in forum Qt Programming
    Replies: 1
    Last Post: 14th November 2006, 09:42
  3. Release mode issue
    By stevey in forum Qt Programming
    Replies: 2
    Last Post: 8th November 2006, 20:26

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.