Commit 27b2d034 authored by Davis King's avatar Davis King

Merge

parents 95d16fd0 0ff862ae
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
#include "../windows_magic.h" #include "../windows_magic.h"
#include <windows.h> #include <windows.h>
#include "../algs.h" #include "../algs.h"
#include <condition_variable>
#include <mutex>
#include <chrono>
namespace dlib namespace dlib
...@@ -43,21 +46,22 @@ namespace dlib ...@@ -43,21 +46,22 @@ namespace dlib
mutex ( mutex (
) )
{ {
InitializeCriticalSection(&cs);
} }
~mutex ( ~mutex (
) { DeleteCriticalSection(&cs); } ) { }
void lock ( void lock (
) const { EnterCriticalSection(&cs); } ) const { cs.lock(); }
void unlock ( void unlock (
) const { LeaveCriticalSection(&cs); } ) const { cs.unlock(); }
private: private:
mutable CRITICAL_SECTION cs; friend class signaler;
mutable std::mutex cs;
// restricted functions // restricted functions
mutex(mutex&); // copy constructor mutex(mutex&); // copy constructor
...@@ -77,147 +81,40 @@ namespace dlib ...@@ -77,147 +81,40 @@ namespace dlib
signaler ( signaler (
const mutex& associated_mutex const mutex& associated_mutex
) : ) :
hSemaphore(CreateSemaphore (NULL, 0, 100000000, NULL)),
waiters(0),
hCountSema(CreateSemaphore (NULL,0,100000000,NULL)),
m(associated_mutex) m(associated_mutex)
{ {
if (hSemaphore == NULL || hCountSema == NULL)
{
if (hSemaphore != NULL)
{
CloseHandle(hSemaphore);
}
if (hCountSema != NULL)
{
CloseHandle(hCountSema);
}
throw dlib::thread_error(ECREATE_SIGNALER,
"in function signaler::signaler() an error occurred making the signaler"
);
}
} }
~signaler ( ~signaler (
) { CloseHandle(hSemaphore); CloseHandle(hCountSema);} ) { }
void wait ( void wait (
) const ) const
{ {
// get a lock on the mutex for the waiters variable std::unique_lock<std::mutex> cs(m.cs, std::defer_lock);
waiters_mutex.lock(); cv.wait(cs);
// mark that one more thread will be waiting on this signaler
++waiters;
// release the mutex for waiters
waiters_mutex.unlock();
// release the associated mutex
m.unlock();
// wait for the semaphore to be signaled
WaitForSingleObject (hSemaphore,INFINITE);
// signal that we are awake
ReleaseSemaphore(hCountSema,(LONG)1,NULL);
// relock the associated mutex
m.lock();
} }
bool wait_or_timeout ( bool wait_or_timeout (
unsigned long milliseconds unsigned long milliseconds
) const ) const
{ {
// get a lock on the mutex for the waiters variable std::unique_lock<std::mutex> cs(m.cs, std::defer_lock);
waiters_mutex.lock(); auto status = cv.wait_until(cs, std::chrono::system_clock::now() + std::chrono::milliseconds(milliseconds));
// mark that one more thread will be waiting on this signaler return status == std::cv_status::no_timeout;
++waiters;
// release the mutex for waiters
waiters_mutex.unlock();
// release the associated mutex
m.unlock();
bool value;
// wait for the semaphore to be signaled
if ( WaitForSingleObject (hSemaphore, milliseconds ) == WAIT_TIMEOUT )
{
// in this case we should decrement waiters because we are returning
// due to a timeout rather than because someone called signal() or
// broadcast().
value = false;
// signal that we are awake
ReleaseSemaphore(hCountSema,(LONG)1,NULL);
// get a lock on the mutex for the waiters variable
waiters_mutex.lock();
// mark that one less thread will be waiting on this signaler.
if (waiters != 0)
--waiters;
// release the mutex for waiters
waiters_mutex.unlock();
}
else
{
value = true;
// signal that we are awake
ReleaseSemaphore(hCountSema,(LONG)1,NULL);
}
// relock the associated mutex
m.lock();
return value;
} }
void signal ( void signal (
) const ) const
{ {
// get a lock on the mutex for the waiters variable cv.notify_one();
waiters_mutex.lock();
if (waiters > 0)
{
--waiters;
// make the semaphore release one waiting thread
ReleaseSemaphore(hSemaphore,1,NULL);
// wait for signaled thread to wake up
WaitForSingleObject(hCountSema,INFINITE);
}
// release the mutex for waiters
waiters_mutex.unlock();
} }
void broadcast ( void broadcast (
) const ) const
{ {
// get a lock on the mutex for the waiters variable cv.notify_all();
waiters_mutex.lock();
if (waiters > 0)
{
// make the semaphore release all the waiting threads
ReleaseSemaphore(hSemaphore,(LONG)waiters,NULL);
// wait for count to be zero
for (unsigned long i = 0; i < waiters; ++i)
{
WaitForSingleObject(hCountSema,INFINITE);
}
waiters = 0;
}
// release the mutex for waiters
waiters_mutex.unlock();
} }
const mutex& get_mutex ( const mutex& get_mutex (
...@@ -225,13 +122,7 @@ namespace dlib ...@@ -225,13 +122,7 @@ namespace dlib
private: private:
mutable HANDLE hSemaphore; mutable std::condition_variable cv;
mutable unsigned long waiters;
mutex waiters_mutex;
mutable HANDLE hCountSema;
const mutex& m; const mutex& m;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment