|
|
Home » Community » Coffee corner » What is the best way to create a Semaphore with timeout?
What is the best way to create a Semaphore with timeout? [message #52857] |
Tue, 17 December 2019 09:49 |
Tom1
Messages: 1242 Registered: March 2007
|
Senior Contributor |
|
|
Hi,
I need a Semaphore with Wait(int timeout_ms); What is the best way (in terms of efficiency) to implement this timeout functionality?
Using SetTimeCallback() to Release() the Semaphore is not an option in non-GUI environment. Another thread Sleeping for the specified amount of time and then calling Release feels a bit inefficient.
(For the background: I'm building a FIFO using BiVector and wish to get minimal latency and overhead for the operation.)
Best regards,
Tom
|
|
|
Re: What is the best way to create a Semaphore with timeout? [message #52858 is a reply to message #52857] |
Tue, 17 December 2019 10:49 |
Tom1
Messages: 1242 Registered: March 2007
|
Senior Contributor |
|
|
Hi,
I took a look at Core and found that Semaphore is really just an abstraction of the OS semaphore.
Now the question is: Would it be possible to change Semaphore code in a way that adds support for timeout? Looking at the code reveals that Windows and Linux/Posix could support Wait(timeout) with minimal changes, but I'm not so sure about OSX.
Best regards,
Tom
|
|
|
Re: What is the best way to create a Semaphore with timeout? [message #52859 is a reply to message #52858] |
Tue, 17 December 2019 11:53 |
Tom1
Messages: 1242 Registered: March 2007
|
Senior Contributor |
|
|
Hi,
I think this is now up to Mirek now...
I have made the needed additions to Semaphore for implementing timeout on Wait.
Here's working code for Windows and Linux:
Mt.h:
...
class Semaphore : NoCopy {
#ifdef PLATFORM_WIN32
HANDLE handle;
#elif PLATFORM_OSX
dispatch_semaphore_t sem;
#else
sem_t sem;
#endif
public:
bool Wait(int timeout_ms); // Added for timeout - returns true if semaphore was signaled, false otherwise
void Wait();
void Release();
#ifdef PLATFORM_WIN32
void Release(int n);
#endif
Semaphore();
~Semaphore();
};
...
Mt.cpp:
...
// For Windows:
bool Semaphore::Wait(int timeout_ms)
{
return WaitForSingleObject(handle, timeout_ms<0 ? INFINITE : timeout_ms) == WAIT_OBJECT_0 ? true : false;
}
...
// For Linux:
bool Semaphore::Wait(int timeout_ms)
{
if(timeout_ms<0){
Wait();
return true;
}
struct timespec until;
clock_gettime(CLOCK_REALTIME, &until);
until.tv_sec+=timeout_ms/1000;
timeout_ms%=1000;
until.tv_nsec+=timeout_ms*1000000;
until.tv_sec+=until.tv_nsec/1000000000;
until.tv_nsec%=1000000000;
return sem_timedwait(&sem,&until)==-1 ? false : true;
}
...
Maybe someone with a Mac could take a look at the OSX code for the same. From what I found on the web, it looks like it could be something like this for OSX:
...
bool Semaphore::Wait(int timeout_ms)
{
if(timeout_ms<0){
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
return true;
}
return dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, 1000000 * timeout_ms)) == 0 ? true : false;
}
...
I hope this makes it to the Core.
Best regards,
Tom
|
|
|
|
|
|
Re: What is the best way to create a Semaphore with timeout? [message #52867 is a reply to message #52865] |
Thu, 19 December 2019 14:38 |
Tom1
Messages: 1242 Registered: March 2007
|
Senior Contributor |
|
|
Hi!
That was fast! Thanks Mirek!!
Now to the Fifo implementation. Does this look right from the point of mutex synchronization? I know this 'appears to work when testing' but I'm new with ConditionVariable, so I'm a bit uncertain if my usage of it is correct. I.e. Will multiple receiving threads calling StringFifo::Get() be correctly served so that each and every String will get read exactly once?
class StringFifo: public BiVector<String>{
ConditionVariable cv;
Mutex mtx;
public:
StringFifo(){
}
void Put(const String &s){
mtx.Enter();
AddTail(s);
cv.Signal();
mtx.Leave();
}
String Get(int timeout_ms=-1){
mtx.Enter();
if(GetCount() || (cv.Wait(mtx,timeout_ms) && GetCount())){
String r=PopHead();
mtx.Leave();
return r;
}
else{
mtx.Leave();
return String::GetVoid();
}
}
};
Thanks and best regards,
Tom
|
|
|
|
|
|
|
Goto Forum:
Current Time: Fri Sep 20 03:49:55 CEST 2024
Total time taken to generate the page: 0.03873 seconds
|
|
|