#include "../memory/safe_ptr.h"\r
\r
#include <concrt.h>\r
-#include <concurrent_queue.h>\r
+#include <queue>\r
+\r
#include <tbb/atomic.h>\r
\r
#include <boost/noncopyable.hpp>\r
{\r
struct impl : std::enable_shared_from_this<impl>\r
{\r
- tbb::atomic<int> count_;\r
- tbb::atomic<int> is_running_;\r
- Concurrency::concurrent_queue<Concurrency::Context*> waiting_contexts_;\r
-\r
+ tbb::atomic<int> count_;\r
+ tbb::atomic<int> is_running_;\r
+ std::queue<Concurrency::Context*> waiting_contexts_;\r
+ Concurrency::critical_section mutex_;\r
+ \r
void acquire_ticket()\r
{\r
if(!is_running_)\r
if(count_ < 1)\r
Concurrency::Context::Yield();\r
\r
- if (--count_ < 0)\r
+ Concurrency::Context* context = nullptr;\r
+\r
{\r
- auto context = Concurrency::Context::CurrentContext();\r
- waiting_contexts_.push(context);\r
- context->Block();\r
+ Concurrency::critical_section::scoped_lock lock(mutex_);\r
+\r
+ if (--count_ < 0)\r
+ {\r
+ context = Concurrency::Context::CurrentContext();\r
+ waiting_contexts_.push(context);\r
+ }\r
}\r
+\r
+ if(context)\r
+ context->Block();\r
}\r
\r
bool try_acquire_ticket()\r
return false;\r
\r
if(count_ < 1)\r
- Concurrency::Context::Yield();\r
+ return false;\r
\r
- if (--count_ < 0)\r
{\r
- ++count_;\r
- return false;\r
+ Concurrency::critical_section::scoped_lock lock(mutex_);\r
+ \r
+ if (--count_ < 0)\r
+ {\r
+ ++count_;\r
+ return false;\r
+ }\r
}\r
+\r
return true;\r
}\r
\r
{\r
if(!is_running_)\r
return;\r
-\r
- if(++count_ <= 0)\r
+ \r
{\r
- Concurrency:: Context* waiting = NULL;\r
- while(!waiting_contexts_.try_pop(waiting))\r
- Concurrency::Context::Yield();\r
- waiting->Unblock();\r
+ Concurrency::critical_section::scoped_lock lock(mutex_);\r
+\r
+ if(++count_ <= 0)\r
+ {\r
+ waiting_contexts_.front()->Unblock();\r
+ waiting_contexts_.pop();\r
+ }\r
}\r
}\r
\r
impl(size_t capacity) \r
{\r
is_running_ = true;\r
- count_ = capacity;\r
+ count_ = capacity;\r
}\r
\r
ticket_t acquire()\r
}));\r
return ticket;\r
}\r
- \r
+ \r
bool try_acquire(ticket_t& ticket)\r
{\r
if(!try_acquire_ticket())\r
return false;\r
\r
auto self = shared_from_this();\r
- ticket.push_back(std::shared_ptr<void>(nullptr, [=](void*)\r
+ ticket.push_back(std::shared_ptr<void>(nullptr, [self](void*)\r
{\r
self->release_ticket();\r
}));\r
void cancel()\r
{\r
is_running_ = false;\r
- Concurrency::Context* waiting = NULL;\r
- while(waiting_contexts_.try_pop(waiting))\r
- waiting->Unblock();\r
+ \r
+ {\r
+ Concurrency::critical_section::scoped_lock lock(mutex_);\r
+ \r
+ while(!waiting_contexts_.empty())\r
+ {\r
+ waiting_contexts_.front()->Unblock();\r
+ waiting_contexts_.pop();\r
+ }\r
+ }\r
}\r
};\r
\r