1 // Copyright (C) 2003  Davis E. King (davis@dlib.net)
2 // License: Boost Software License   See LICENSE.txt for the full license.
3 #ifndef DLIB_THREADS_KERNEl_1_
4 #define DLIB_THREADS_KERNEl_1_
5 
6 #ifdef DLIB_ISO_CPP_ONLY
7 #error "DLIB_ISO_CPP_ONLY is defined so you can't use this OS dependent code.  Turn DLIB_ISO_CPP_ONLY off if you want to use it."
8 #endif
9 
10 #include "threads_kernel_abstract.h"
11 
12 #include "../windows_magic.h"
13 #include <windows.h>
14 #include "../algs.h"
15 #include <condition_variable>
16 #include <mutex>
17 #include <chrono>
18 
19 
20 namespace dlib
21 {
22 
23 // ----------------------------------------------------------------------------------------
24 
25     typedef DWORD thread_id_type;
26 
get_thread_id()27     inline thread_id_type get_thread_id (
28     )
29     {
30         return GetCurrentThreadId();
31     }
32 
33 // ----------------------------------------------------------------------------------------
34 // ----------------------------------------------------------------------------------------
35     // mutex object
36 // ----------------------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------------------
38 
39     // forward declaration of signaler
40     class signaler;
41 
42     class mutex
43     {
44     public:
45 
mutex()46         mutex (
47         )
48         {
49         }
50 
~mutex()51         ~mutex (
52         ) {  }
53 
lock()54         void lock (
55         ) const { cs.lock(); }
56 
unlock()57         void unlock (
58         ) const { cs.unlock(); }
59 
60     private:
61 
62         friend class signaler;
63 
64         mutable std::mutex cs;
65 
66         // restricted functions
67         mutex(mutex&);        // copy constructor
68         mutex& operator=(mutex&);    // assignment operator
69     };
70 
71 // ----------------------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------------------
73     // signaler object
74 // ----------------------------------------------------------------------------------------
75 // ----------------------------------------------------------------------------------------
76 
77     class signaler
78     {
79 
80     public:
signaler(const mutex & associated_mutex)81         signaler (
82             const mutex& associated_mutex
83         ) :
84             m(associated_mutex)
85         {
86 
87         }
88 
~signaler()89         ~signaler (
90         ) { }
91 
wait()92         void wait (
93         ) const
94         {
95             std::unique_lock<std::mutex> cs(m.cs, std::defer_lock);
96             cv.wait(cs);
97         }
98 
wait_or_timeout(unsigned long milliseconds)99         bool wait_or_timeout (
100             unsigned long milliseconds
101         ) const
102         {
103             std::unique_lock<std::mutex> cs(m.cs, std::defer_lock);
104             auto status = cv.wait_until(cs, std::chrono::system_clock::now() + std::chrono::milliseconds(milliseconds));
105             return status == std::cv_status::no_timeout;
106         }
107 
signal()108         void signal (
109         ) const
110         {
111             cv.notify_one();
112         }
113 
broadcast()114         void broadcast (
115         ) const
116         {
117             cv.notify_all();
118         }
119 
get_mutex()120         const mutex& get_mutex (
121         ) const { return m; }
122 
123     private:
124 
125         mutable std::condition_variable cv;
126 
127         const mutex& m;
128 
129         // restricted functions
130         signaler(signaler&);        // copy constructor
131         signaler& operator=(signaler&);    // assignment operator
132     };
133 
134 // ----------------------------------------------------------------------------------------
135 
136     namespace threads_kernel_shared_helpers
137     {
138         bool spawn_thread (
139             void (*funct)(void*),
140             void* param
141         );
142         /*!
143             is identical to create_new_thread() but just doesn't use any thread pooling.
144         !*/
145     }
146 
147 // ----------------------------------------------------------------------------------------
148 
149 }
150 
151 #include "threads_kernel_shared.h"
152 
153 #ifdef NO_MAKEFILE
154 #include "threads_kernel_1.cpp"
155 #endif
156 
157 #endif // DLIB_THREADS_KERNEl_1_
158 
159