C++ Rest SDK
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.
pplxwin.h
1 /***
2 * ==++==
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * ==--==
17 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
18 *
19 * Windows specific pplx implementations
20 *
21 * For the latest on this and related APIs, please see http://casablanca.codeplex.com.
22 *
23 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
24 ****/
25 
26 #pragma once
27 
28 #if !defined(_WIN32) || _MSC_VER < 1800 || CPPREST_FORCE_PPLX
29 
30 #include "cpprest/details/cpprest_compat.h"
31 #include "pplx/pplxinterface.h"
32 
33 namespace pplx
34 {
35 
36 namespace details
37 {
38  namespace platform
39  {
43  _PPLXIMP long __cdecl GetCurrentThreadId();
44 
48  _PPLXIMP void __cdecl YieldExecution();
49 
53  __declspec(noinline) _PPLXIMP size_t __cdecl CaptureCallstack(void **, size_t, size_t);
54 
55 #if defined(__cplusplus_winrt)
56  // Internal API which retrieves the next async id.
59  _PPLXIMP unsigned int __cdecl GetNextAsyncId();
60 #endif
61  }
62 
66  class event_impl
67  {
68  public:
69 
70  static const unsigned int timeout_infinite = 0xFFFFFFFF;
71 
72  _PPLXIMP event_impl();
73 
74  _PPLXIMP ~event_impl();
75 
76  _PPLXIMP void set();
77 
78  _PPLXIMP void reset();
79 
80  _PPLXIMP unsigned int wait(unsigned int timeout);
81 
82  unsigned int wait()
83  {
84  return wait(event_impl::timeout_infinite);
85  }
86 
87  private:
88  // Windows events
89  void * _M_impl;
90 
91  event_impl(const event_impl&); // no copy constructor
92  event_impl const & operator=(const event_impl&); // no assignment operator
93  };
94 
99  {
100  public:
101 
102  _PPLXIMP critical_section_impl();
103 
104  _PPLXIMP ~critical_section_impl();
105 
106  _PPLXIMP void lock();
107 
108  _PPLXIMP void unlock();
109 
110  private:
111 
112  typedef void * _PPLX_BUFFER;
113 
114  // Windows critical section
115  _PPLX_BUFFER _M_impl[8];
116 
117  critical_section_impl(const critical_section_impl&); // no copy constructor
118  critical_section_impl const & operator=(const critical_section_impl&); // no assignment operator
119  };
120 
121 #if _WIN32_WINNT >= _WIN32_WINNT_VISTA
126  {
127  public:
128 
129  class scoped_lock_read
130  {
131  public:
132  explicit scoped_lock_read(reader_writer_lock_impl &_Reader_writer_lock) : _M_reader_writer_lock(_Reader_writer_lock)
133  {
134  _M_reader_writer_lock.lock_read();
135  }
136 
137  ~scoped_lock_read()
138  {
139  _M_reader_writer_lock.unlock();
140  }
141 
142  private:
143  reader_writer_lock_impl& _M_reader_writer_lock;
144  scoped_lock_read(const scoped_lock_read&); // no copy constructor
145  scoped_lock_read const & operator=(const scoped_lock_read&); // no assignment operator
146  };
147 
148  _PPLXIMP reader_writer_lock_impl();
149 
150  _PPLXIMP void lock();
151 
152  _PPLXIMP void lock_read();
153 
154  _PPLXIMP void unlock();
155 
156  private:
157 
158  // Windows slim reader writer lock
159  void * _M_impl;
160 
161  // Slim reader writer lock doesn't have a general 'unlock' method.
162  // We need to track how it was acquired and release accordingly.
163  // true - lock exclusive
164  // false - lock shared
165  bool m_locked_exclusive;
166  };
167 #endif // _WIN32_WINNT >= _WIN32_WINNT_VISTA
168 
172  class recursive_lock_impl
173  {
174  public:
175 
176  recursive_lock_impl()
177  : _M_owner(-1), _M_recursionCount(0)
178  {
179  }
180 
181  ~recursive_lock_impl()
182  {
183  _ASSERTE(_M_owner == -1);
184  _ASSERTE(_M_recursionCount == 0);
185  }
186 
187  void recursive_lock_impl::lock()
188  {
189  auto id = ::pplx::details::platform::GetCurrentThreadId();
190 
191  if ( _M_owner == id )
192  {
193  _M_recursionCount++;
194  }
195  else
196  {
197  _M_cs.lock();
198  _M_owner = id;
199  _M_recursionCount = 1;
200  }
201  }
202 
203  void recursive_lock_impl::unlock()
204  {
205  _ASSERTE(_M_owner == ::pplx::details::platform::GetCurrentThreadId());
206  _ASSERTE(_M_recursionCount >= 1);
207 
208  _M_recursionCount--;
209 
210  if ( _M_recursionCount == 0 )
211  {
212  _M_owner = -1;
213  _M_cs.unlock();
214  }
215  }
216 
217  private:
219  long _M_recursionCount;
220  volatile long _M_owner;
221  };
222 
223  class windows_scheduler : public pplx::scheduler_interface
224  {
225  public:
226  _PPLXIMP virtual void schedule( TaskProc_t proc, _In_ void* param);
227  };
228 
229 } // namespace details
230 
235 template<class _Lock>
236 class scoped_lock
237 {
238 public:
239  explicit scoped_lock(_Lock& _Critical_section) : _M_critical_section(_Critical_section)
240  {
241  _M_critical_section.lock();
242  }
243 
244  ~scoped_lock()
245  {
246  _M_critical_section.unlock();
247  }
248 
249 private:
250  _Lock& _M_critical_section;
251 
252  scoped_lock(const scoped_lock&); // no copy constructor
253  scoped_lock const & operator=(const scoped_lock&); // no assignment operator
254 };
255 
256 // The extensibility namespace contains the type definitions that are used internally
257 namespace extensibility
258 {
259  typedef ::pplx::details::event_impl event_t;
260 
261  typedef ::pplx::details::critical_section_impl critical_section_t;
262  typedef scoped_lock<critical_section_t> scoped_critical_section_t;
263 
264 #if _WIN32_WINNT >= _WIN32_WINNT_VISTA
265  typedef ::pplx::details::reader_writer_lock_impl reader_writer_lock_t;
266  typedef scoped_lock<reader_writer_lock_t> scoped_rw_lock_t;
267  typedef reader_writer_lock_t::scoped_lock_read scoped_read_lock_t;
268 #endif // _WIN32_WINNT >= _WIN32_WINNT_VISTA
269 
270 
271  typedef ::pplx::details::recursive_lock_impl recursive_lock_t;
272  typedef scoped_lock<recursive_lock_t> scoped_recursive_lock_t;
273 }
274 
278 typedef details::windows_scheduler default_scheduler_t;
279 
280 namespace details
281 {
285 
286  #ifndef _REPORT_PPLTASK_UNOBSERVED_EXCEPTION
287  #define _REPORT_PPLTASK_UNOBSERVED_EXCEPTION() do { \
288  __debugbreak(); \
289  std::terminate(); \
290  } while(false)
291  #endif // _REPORT_PPLTASK_UNOBSERVED_EXCEPTION
292 
293 } // namespace details
294 
295 } // namespace pplx
296 
297 #endif
void(_pplx_cdecl * TaskProc_t)(void *)
An elementary abstraction for a task, defined as void (__cdecl * TaskProc_t)(void *)...
Definition: pplxinterface.h:59
A generic RAII wrapper for locks that implements the critical_section interface cpprest_synchronizati...
Definition: pplxlinux.h:264
The pplx namespace provides classes and functions that give you access to the Concurrency Runtime...
Definition: pplx.h:81
struct __declspec(novtable) scheduler_interface
Scheduler Interface
Definition: pplxinterface.h:64
Definition: pplxwin.h:223
Mutex - lock for mutual exclusion
Definition: pplxwin.h:98
Reader writer lock
Definition: pplxlinux.h:140
details::linux_scheduler default_scheduler_t
Default scheduler type
Definition: pplxlinux.h:306