PDA

View Full Version : QT 4.7.4 vs QT4.8.4 QMutexLocker works one machine not another vice versa



barrygp
4th June 2013, 16:57
Hi,

If I build my code with QT4.7.4 it will run on machine 1 but will only run on machine 2 for about 15 minutes then freeze. If I build the same code with Qt4.8.4 it will run on machine 2 but will only run on machine 1 for about 15 minuters then freezes. If I take out the use of a QMutexLocker it appears to run fine on either machine.
The machines are both windows Server 2003, and machine 1 has a dual X5260 processors and machine 2 has four E5410 processors. Both have 4 Gig Memory.
Is there a registry setting or anything that I can check as to why I am seeing this bevavour?

Thanks.

pkj
4th June 2013, 17:30
The QMutex you are using with QMutexLocker, which mode is it in. Is in QMutex::Recursive or QMutex::NonRecursive mode? Also can you elaborate whether the function is not a recursive calling function?
Also do you get an message with assert failure like this:
ASSERT failure in QMutexLocker: "QMutex pointer is misaligned"

barrygp
4th June 2013, 22:21
The function is not recursive, and can only run in release mode on these machines, but do not get the ASSERT message. Below is sample of how I am using the mutex.
// .h file snippet

private:
QMutex outReqsMutex_;
// other defines below
------------------------------
// .cpp file snippet below

int client::getStatus()
{
QUrl url = buildUrl("/pxs/status");
QMutexLocker ml(&outReqsMutex_);

// Is there an outstanding request for this URL?
if (outstandingRequests_.contains(serverHost, url)) {
return 0;
}

// send the request below
// Add the URL to the outstanding set.
outstandingRequests_.insert(serverHost, url);

QNetworkReply *nr = NULL;
QNetworkRequest netReq(url);
netReq.setHeader(QNetworkRequest::ContentTypeHeade r, CPS_MIME_TYPE_TEXTPLAIN_UTF8);
nr = networkManager.get(netReq);
replyQueue_.insert(nr, QDateTime::currentDateTime());
return 1;
}

/////////
// within the network request finish slot I lock and remove from the map
{
QMutexLocker ml(&outReqsMutex_);
int nnum = replyQueue_.remove(reply);
outstandingRequests_.remove(reply->url().host(), reply->url());
}

thanks.

pkj
5th June 2013, 06:35
Two functions share a mutex. So if funcA while running on ThreadA calls funcB, it tries to regain a non-recursive lock.
as you know a single mutex should only ever be acquired once by a single thread within the same call chain. Attempting to acquire (or hold) the same mutex twice, within the same thread context, should be considered an invalid scenario, and should be handled appropriately (usually via an ASSERT as you are breaking a fundamental contract of your code).
So you need to make sure that (a) your mutex is non-recursive. (b) functions with the lock are exclusive.

And if the network request finish slot is only used as a slot, and not called as a function anywhere else... we may be sure that the function will be executed only on the thread the class resides...