I can't find any information on this with Google, so I post here hoping that someone can help...
My problem is with the Windows pthread function pthread_cond_timedwait(). When the indicated time is elapsed, the function should return with value ETIMEDOUT. Instead in my code, where its conditional variable is not signaled, it returns the value 138 and does it much earlier than the expected timeout, sometimes immediately.
So my questions are: what is this error 138? And why is the timeout not completely elapsed?
The code I use for the thread is:
int retcode = 0;
timeb tb;
ftime(&tb);
struct timespec timeout;
timeout.tv_sec = tb.time + 8;
timeout.tv_nsec = tb.millitm * 1000 * 1000;
pthread_mutex_lock(&mutex_);
retcode = pthread_cond_timedwait(&cond_, &mutex_, &timeout);
pthread_mutex_unlock(&mutex_);
if (retcode == ETIMEDOUT)
{
addLog("Timed-out. Sending request...", LOG_DEBUG);
}
else // Something happened
{
std::stringstream ss;
ss << "Thread interrupted (Error " << retcode << ")";
addLog(ss.str().c_str(), LOG_DEBUG);
}
Is there something wrong with my absolute timeout computation?
Only this thread and the calling thread are present. The calling one joins the created one just after its creation and correctly waits until it finishes.
Currently the conditional variable cond_ is never signaled, but if I try to do it, the pthread_cond_timedwait() returns with value 0 as expected.
Even if not shown here, both cond_ and mutex_ are correctly initialised (if I dont't do it, I get a EINVAL error).
Also following the pthread code I can't find this error. I can only find some return errno that could produce it, but I don't know the meaning of the 138.
If it can help, I am using Visual Studio 2003 with pthreads win32 v2.9.1.
Thanks,
RG
Maybe this answer will be helpful for someone.
I encountered with the same issue. pthread_cond_timedwait returns error 138
I rummaged all source code of pthread_win32 but didn't find anything similar to error code 138.
I downloaded source code of pthread, built it with Visual studio 2008 and... all work nice! :(
Cause of such behaviour is that precompilled dll was built with MSVC100, but I build my app with MSVC90. ETIMEDOUT in MSVC100 is 138, but in MSVC90 is 10060.
Thats all! It is Windows, bro!
Related
I've hit a bit of an issue and I'm not sure what to make of it.
I'm running Qt 4.8.6, Qt creator 3.3.2, environment in Ubuntu 12.04 cross compiling to a Beaglebone Black running Debian 7 kernel 3.8.13.
The issue that I'm seeing is that this code:
if (qApp->hasPendingEvents())
{
qDebug() << "pending events";
}
qApp->processEvents(QEventLoop::AllEvents, 10);
does not function as it should according to (at least my interpretation of) the Qt documentation. I would expect the process events loop to function for AT MOST the 10 milliseconds specified.
What happens is the qDebug statement is never printed. I would then expect that there are therefore no events to be processed, and the process events statement goes in and out very quickly. Most of the time this is the case.
What happens (not every time, but often enough) the qDebug statement is skipped, and the processEvents statement executes for somewhere between 1 and 2 seconds.
Is there some way that I can dig into what is happening in the process events and find out what is causing the delay?
Qt is processing events for longer than specified for QApplication::processEvents call on Linux
system. Is there some way that I can dig into what is happening in the
process events and find out what is causing the delay?
Yes, observing Qt source code may help. The source code is in /home/myname/software/Qt/5.5/Src/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp or maybe somewhere around that:
bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QEventDispatcherUNIX);
d->interrupt.store(0);
// we are awake, broadcast it
emit awake();
// This statement implies forcing events from system event queue
// to be processed now with doSelect below
QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
int nevents = 0;
const bool canWait = (d->threadData->canWaitLocked()
&& !d->interrupt.load()
&& (flags & QEventLoop::WaitForMoreEvents));
if (canWait)
emit aboutToBlock();
if (!d->interrupt.load()) {
// return the maximum time we can wait for an event.
timespec *tm = 0;
timespec wait_tm = { 0l, 0l };
if (!(flags & QEventLoop::X11ExcludeTimers)) {
if (d->timerList.timerWait(wait_tm))
tm = &wait_tm;
}
if (!canWait) {
if (!tm)
tm = &wait_tm;
// no time to wait
tm->tv_sec = 0l;
tm->tv_nsec = 0l;
}
// runs actual event loop with POSIX select
nevents = d->doSelect(flags, tm);
It seems there system posted events that are not accounted for qApp->hasPendingEvents(). And then QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); flushes those events to be processed by d->doSelect. If I was solving this task I would try to either flush those posted events out or maybe realize if and why flags parameter has QEventLoop::WaitForMoreEvents bit set. I usually either build Qt from source code or provide debugger with the path to its symbols/source so it is possible to dig in there.
P.S. I glanced at Qt 5.5.1 source event processing code but that should be very similar to what you deal with. Or could that implementation actually be bool QEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)? It is easy to find on an actual system.
I have a C++ application that includes this function:
int
mySelect(const int fdMaxPlus1,
fd_set *readFDset,
fd_set *writeFDset,
struct timeval *timeout)
{
retry:
const int selectReturn
= ::select(fdMaxPlus1, readFDset, writeFDset, NULL, timeout);
if (selectReturn < 0 && EINTR == errno) {
// Interrupted system call, such as for profiling signal, try again.
goto retry;
}
return selectReturn;
}
Normally, this code work just fine, however, in one instance, I saw it get into an infinite loop where select() keeps failing with the EINTR errno code. In this case, the caller had set the timeout to zero seconds and zero microseconds, meaning don't wait and return the select() result immediately. I thought that EINTR only occurs when a signal handler occurred, why would I keep getting a signal handler over and over again (for over 12 hours)? This is Centos 5. Once I put this into the debugger to see what was happening, the code returned without EINTR after a couple iterations. Note that the fd being checked is a socket.
I could add a retry limit to the above code, but I'd like to understand what is going on first.
On Linux, select(2) may modify the timeout argument (passed by address). So you should copy it after the call.
retry:
struct timeout timeoutcopy = timeout;
const int selectReturn
= ::select(fdMaxPlus1, readFDset, writeFDset, NULL, &timeoutcopy);
(in your code, your timeout is probably zero or very small after a few or even the first iterations)
BTW, I suggest rather using poll(2) instead of select (since poll is is more C10K problem friendly)
BTW, EINTR happens on any signal (see signal(7)), even without a registered signal handler.
You might use strace to understand the overall behavior of your program.
I have 2 applications sharing the same lock file, and I need to know when the
the other application has either locked/unlocked the file. The code below was
originally implemented on a Linux machine, and is being ported to Window 8, VS12.
I have ported all other code in the class successfully and am locking files with
LockFile(handle, 0, 0, sizeof(int), 0) and the equivalent UnlockFile(...). However,
I am having trouble with the following wait() command.
bool devices::comms::CDeviceFileLock::wait(bool locked,
int timeout)
{
// Retrieve the current pid of the process.
pid_t pid = getpid();
// Determine if we are tracking time.
bool tracking = (timeout > 0);
// Retrieve the lock information.
struct flock lock;
if (fcntl(m_iLockFile, F_GETLK, &lock) != 0)
raiseException("Failed to retrieve lock file information");
// Loop until the state changes.
time_t timeNow = time(NULL);
while ((pid == lock.l_pid)
&&
(lock.l_type != (locked ? F_WRLCK : F_UNLCK)))
{
// Retrieve the lock information.
if (fcntl(m_iLockFile, F_GETLK, &lock) != 0)
raiseException("Failed to retrieve lock file information");
// Check for timeout, if we are tracking.
if (tracking)
{
time_t timeCheck = time(NULL);
if (difftime(timeNow, timeCheck) > timeout)
return false;
}
}
// Return success.
return true;
}
Note: m_iLockFile used to be a file descriptor from open(), it is now called
m_hLockFile and is a HANDLE from CreateFile().
I cannot seem to find the Windows equivalent of the fcntl F_GETLK command.
Does anyone know if I can either:
a) use an fcntl equivalent to interrogate locking information, to find out
which process has obtained the lock
b) suggest how the above can be re-written for Windows C++.
Note: The server application using the lock file is a standalone C++ executable,
however the client using the lock file is a WinRT Windows Application. So any
suggested solution cannot break the sandboxing of the client.
Thanks.
You are not going to find this in Windows, it is fundamentally unsound on a multi-tasking operating system. The value you'd get from an IsFileLocked() api function is meaningless, another process or thread could still lock the file a microsecond later.
The workaround is simple, if you need to lock then just try to acquire one. If the file is already locked then LockFile() will simply return FALSE, GetLastError() tells you why. Now it is atomic, an essential property of a lock. If you can afford to wait for the lock then use LockFileEx() without the LOCKFILE_FAIL_IMMEDIATELY option.
I am just googling for you, but I found this
"Various C language run-time systems use the IOCTLs for purposes
unrelated to Windows Sockets. As a consequence, the ioctlsocket
function and the WSAIoctl function were defined to handle socket
functions that were performed by IOCTL and fcntl in the Berkeley
Software Distribution."
There is also a brief discussion here - it is python based but has some clues.
I'm writing a program in C++ using WINAPI to monitor certain directory for new files arriving, and send them in certain order. The files are derived from a live video stream, so there are 2 files in a unit - audio file and video file, and units should be sent in sequence. a. k. a. (1.mp3, 1.avi); (2.mp3, 2.avi)... Architecture is:
1) detect a new file added to the folder, insert file name to the input queue
2) organize files into units, insert units into unit queue
3) send unit by unit
But since I have to use monitoring file directory for files added there, I need to make sure that file is complete, a. k. a. it is ready to send, since the signal appears when the file is created, but it has yet to be filled with info and closed. So I pop file name from a input queue either when queue has more than 1 file (a. k. a. signal came for next file created, that means that previous file is ready to send) or on timeout(10 sec) so for 10 seconds any file should be done.
So in general this program runs and works properly. But, if I assume that the send procedure will take too long time, so the unit queue will grow. And after some number of units buffered in a unit queue the bug appears.
time[END] = 0;
time[START] = clock();
HANDLE hIOMutex2= CreateMutex (NULL, FALSE, NULL);
WaitForSingleObject( hIOMutex2, INFINITE );
hTimer = CreateThread(NULL, 0, Timer, time, 0, &ThreadId1);
if(hTimer == NULL)
printf("Timer Error\n");
ReleaseMutex(hIOMutex2);
ReadDirectoryChangesW(hDir, szBuffer, sizeof(szBuffer) / sizeof(TCHAR), FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, &dwBytes, NULL, NULL);
HANDLE hIOMutex= CreateMutex (NULL, FALSE, NULL);
WaitForSingleObject( hIOMutex, INFINITE );
time[END] = clock();
TerminateThread(hTimer, 0);
ReleaseMutex( hIOMutex);
After around 800 units buffered in a queue, my program gives me "Time Error" message, if I'm right that means that program can't allocate thread. But in this code program terminates timer thread exactly after the file was created in a directory. So I'm kind of confused with this bug. Also interesting is that even with this time error, my program continue to send units as usual, so that doesn't look like a OS mistake or something different, it is wrong thread declaration/termination, at least it seems like that to me.
Also providing Timer code below if it is helpful.
DWORD WINAPI Timer(LPVOID in){
clock_t* time = (clock_t*) in;
while(TRUE){
if(((clock() - time[START])/CLOCKS_PER_SEC >= 10) && (!time[END]) && (!output.empty())){
Send();
if(output.empty()){
ExitThread(0);
}
}
else if((output.empty()) || (time[END])){
break;
}
else{
Sleep(10);
}
}
ExitThread(0);
return 0;
}
Please could anyone here give me some advise how to solve this bug? Thanks in advance.
Using TerminateThread is a bad idea in many ways. In your case, it makes your program fail because it doesn't release the memory for the thread stack. Failure comes when your program has consumed all available virtual memory and CreateThread() cannot reserve enough memory for another thread. Only ever use TerminateThread while exiting a program.
You'll have to do this a smarter way. Either by asking a thread to exit nicely by signaling an event or by just not consuming such an expensive system resource only for handling a file. A simple timer and one thread can do this too.
The following code runs perfectly well on my XP SP2 machine, but the call to WaitForSingleObject waits indefinitely when running on my Vista machine:
HANDLE ghSemaphore;
ghSemaphore = CreateSemaphore(NULL, 0, 1, "COM_PHILOERTEL_FINA");
if (ghSemaphore == NULL) {
MessageBoxA(NULL,"Error creating semaphore","ERROR",0);
return FALSE;
}
MessageBoxA(NULL,"Semaphore created. Waiting for it to be triggered","ERROR",0);
WaitForSingleObject(ghSemaphore, INFINITE);
// got the semaphore, ready to rock
MessageBoxA(NULL,"Got the semaphore, ready to rock!","Notice",0);
Here's the thread that releases the semaphore:
ghSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "COM_PHILOERTEL_FINA");
if (ghSemaphore == NULL) {
MessageBoxA(NULL,"Failed to open semaphore","ERROR",0);
return FALSE;
}
if (0 == ReleaseSemaphore(ghSemaphore, 1, NULL)) {
MessageBoxA(NULL,"Plugin was unable to release the semaphore","ERROR",0);
return FALSE;
}
The named semaphore was a recent addition that didn't do any good. Before that the threads were just sharing ghSemaphore with its anonymous semaphore. No apparent difference. Does anyone have any idea why this binary (compiled on the XP machine in VC6, Express Edition fwiw) wouldn't work in Vista? As I said above, the WaitForSingleObject call is what never finishes.
THanks!
I cannot check it right now, but heard about it, so try:
Change first argument of CreateSemaphore from NULL to empty instance of SECURITY_ATTRIBUTES
SECURITY_ATTRIBUTES dumy;
dumy.nLength = sizeof(dumy);
dumy.lpSecurityDescriptor = 0;
dumy.bInheritHandle = TRUE;
CreateSemaphore(&dumy, 0, 1, "COM_PHILOERTEL_FINA");
By the way named semaphore with lMaximumCount = 1 is fully equivalent of named mutex. So review possibility to use mutex.
Solved. This was entirely user error. Thanks #Dewfy, #Naveen, and #avakar for your thoughtful responses.
I was sure the user function was being called because I was displaying its result in my Filemaker layout. What I failed to realize is that these return values are cached by default. The function was never being called. Your suggestions were really helpful, because it wasn't until I fully understood what I was doing with my threads and semaphores that I was able to step back and say "hang on, something's not right here".
I'm still grappling with the mystery of why when I removed the semaphore code I was able to access the resource that the user function was supposed to provide, even though that function was not running. But that's a separate issue.
feels GOOD