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.
threadpool.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 * Simple Linux implementation of a static thread pool.
19 *
20 * For the latest on this and related APIs, please see http://casablanca.codeplex.com.
21 *
22 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
23 ***/
24 #pragma once
25 
26 #include <pthread.h>
27 #include <vector>
28 
29 #if defined(__clang__)
30 #pragma clang diagnostic push
31 #pragma clang diagnostic ignored "-Wconversion"
32 #pragma clang diagnostic ignored "-Wunreachable-code"
33 #endif
34 #include "boost/asio.hpp"
35 #if defined(__clang__)
36 #pragma clang diagnostic pop
37 #endif
38 
39 #if (defined(ANDROID) || defined(__ANDROID__))
40 #include <atomic>
41 #include <jni.h>
42 #include "pplx/pplx.h"
43 #endif
44 
45 namespace crossplat {
46 
47 #if (defined(ANDROID) || defined(__ANDROID__))
48 // IDEA: Break this section into a separate android/jni header
49 extern std::atomic<JavaVM*> JVM;
50 JNIEnv* get_jvm_env();
51 
52 struct java_local_ref_deleter
53 {
54  void operator()(jobject lref) const
55  {
56  crossplat::get_jvm_env()->DeleteLocalRef(lref);
57  }
58 };
59 
60 template<class T>
61 using java_local_ref = std::unique_ptr<typename std::remove_pointer<T>::type, java_local_ref_deleter>;
62 #endif
63 
65 {
66 public:
67 
68  threadpool(size_t n)
69  : m_service(n),
70  m_work(m_service)
71  {
72  for (size_t i = 0; i < n; i++)
73  add_thread();
74  }
75 
76  static threadpool& shared_instance();
77 
78  ~threadpool()
79  {
80  m_service.stop();
81  for (auto iter = m_threads.begin(); iter != m_threads.end(); ++iter)
82  {
83  pthread_t t = *iter;
84  void* res;
85  pthread_join(t, &res);
86  }
87  }
88 
89  template<typename T>
90  void schedule(T task)
91  {
92  m_service.post(task);
93  }
94 
95  boost::asio::io_service& service()
96  {
97  return m_service;
98  }
99 
100 private:
101  struct _cancel_thread { };
102 
103  void add_thread()
104  {
105  pthread_t t;
106  auto result = pthread_create(&t, nullptr, &thread_start, this);
107  if (result == 0)
108  m_threads.push_back(t);
109  }
110 
111  void remove_thread()
112  {
113  schedule([]() -> void { throw _cancel_thread(); });
114  }
115 
116 #if (defined(ANDROID) || defined(__ANDROID__))
117  static void detach_from_java(void*)
118  {
119  JVM.load()->DetachCurrentThread();
120  }
121 #endif
122 
123  static void* thread_start(void *arg)
124  {
125 #if (defined(ANDROID) || defined(__ANDROID__))
126  // Calling get_jvm_env() here forces the thread to be attached.
127  get_jvm_env();
128  pthread_cleanup_push(detach_from_java, nullptr);
129 #endif
130  threadpool* _this = reinterpret_cast<threadpool*>(arg);
131  try
132  {
133  _this->m_service.run();
134  }
135  catch (const _cancel_thread&)
136  {
137  // thread was cancelled
138  }
139  catch (...)
140  {
141  // Something bad happened
142 #if (defined(ANDROID) || defined(__ANDROID__))
143  // Reach into the depths of the 'droid!
144  // NOTE: Uses internals of the bionic library
145  // Written against android ndk r9d, 7/26/2014
146  __pthread_cleanup_pop(&__cleanup, true);
147  throw;
148 #endif
149  }
150 #if (defined(ANDROID) || defined(__ANDROID__))
151  pthread_cleanup_pop(true);
152 #endif
153  return arg;
154  }
155 
156  std::vector<pthread_t> m_threads;
157  boost::asio::io_service m_service;
158  boost::asio::io_service::work m_work;
159 };
160 
161 }
Definition: threadpool.h:45
Definition: threadpool.h:64