summaryrefslogtreecommitdiff
path: root/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h
blob: 2ba8a45bf58366b9702cef5fbad10b73dbd6b9c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
// -*- C++ -*-

//=============================================================================
/**
 *  @file DTP_Thread_Pool.h
 *
 *  @author Irfan Pyarali
 *  @author Johnny Willemsen
 *  @author Phil Mesnier
 */
// ===================================================================

#ifndef TAO_DTP_THREAD_POOL_H
#define TAO_DTP_THREAD_POOL_H

#include /**/ "ace/pre.h"
#include "tao/orbconf.h"

#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#include "ace/Hash_Map_Manager.h"
#include "tao/Thread_Lane_Resources.h"
#include "tao/Dynamic_TP/dynamic_tp_export.h"
#include "tao/Dynamic_TP/DTP_Config.h"
#include "tao/New_Leader_Generator.h"
#include "ace/Task.h"
#include "ace/Null_Mutex.h"

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

class TAO_ORB_Core;
class TAO_DTP_Thread_Pool;
class TAO_DTP_Thread_Pool_Manager;

/**
 * @class TAO_DTP_New_Leader_Generator
 *
 * @brief Class for creating dynamic threads.
 *
 * \nosubgrouping
 *
 **/
class TAO_Dynamic_TP_Export TAO_DTP_New_Leader_Generator
  : public TAO_New_Leader_Generator
{
public:
  /// Constructor.
  TAO_DTP_New_Leader_Generator (TAO_DTP_Thread_Pool &lane);

  /// Leader/Follower class uses this method to notify the system that
  /// we are out of leaders.
  bool no_leaders_available (void);

private:
  /// Pool associated with this leader generator.
  TAO_DTP_Thread_Pool &pool_;
};

/**
 * @class TAO_DTP_Thread_Pool_Threads
 *
 * @brief Class representing a static thread running in a thread lane.
 *
 * \nosubgrouping
 *
 **/
class TAO_DTP_Thread_Pool_Threads : public ACE_Task_Base
{
public:
  /// Constructor.
  TAO_DTP_Thread_Pool_Threads (TAO_DTP_Thread_Pool &pool);

  /// Method executed when a thread is spawned.
  int svc (void);

  /// Accessor to the pool to which this thread belongs to.
  TAO_DTP_Thread_Pool &pool (void) const;

protected:
  /// Do the real work
  virtual int run (TAO_ORB_Core &orb_core);

  /// Pool to which this thread belongs to.
  TAO_DTP_Thread_Pool &pool_;
};

/**
 * @class TAO_DTP_Termination_Waiter
 *
 * @brief A thread pool helper that simply waits for the detached
 * threads to signal their termination so ORB shutdown can be orderly
 *
 **/
class TAO_DTP_Termination_Waiter : public ACE_Task_Base
{
public:
  /// Constructor.
  TAO_DTP_Termination_Waiter (TAO_DTP_Thread_Pool &pool);

  /// Method executed when a thread is spawned.
  int svc (void);

protected:
  /// Pool to which this thread belongs to.
  TAO_DTP_Thread_Pool &pool_;
};

/**
 * @class TAO_DTP_Thread_Pool
 *
 * @brief Class representing the thread pool inside a thread pool
 * manager.
 *
 * \nosubgrouping
 *
 **/
class TAO_Dynamic_TP_Export TAO_DTP_Thread_Pool
{
public:
  friend class TAO_DTP_Thread_Pool_Threads;
  friend class TAO_DTP_Termination_Waiter;

  TAO_DTP_Thread_Pool (TAO_DTP_Thread_Pool_Manager &manager,
                       CORBA::ULong id,
                       TAO_DTP_Definition &definition);

  /// Destructor.
  ~TAO_DTP_Thread_Pool (void);

  /// Open the pool.
  void open (void);

  /// Wait for threads to exit.
  void wait (void);

  /// Mark this thread pool that we are shutting down.
  void shutting_down (void);

  /// Create the initial threads - only called once.
  int create_initial_threads (void);

  /// Called by the TAO_DTP_New_Leader_Generator to request a new dynamic
  /// thread.
  /**
   * It can be that no thread can be created because the number of
   * threads is equal to the maximum we can have or the Thread Lane
   * is shutting down.
   * @retval true A new thread is created
   * @retval false No thread could be created
   */
  bool new_dynamic_thread (void);

  /// Called by the run loop to determine if to expire a thread or not
  /// when the dynamic timeout is reached.
  bool above_minimum (void);

  /// @name Accessors
  // @{

  bool use_timeouts (void) const;
  const ACE_Time_Value& dynamic_thread_time (void) const;

  TAO_DTP_Thread_Pool_Manager &manager (void) const;
  CORBA::ULong id (void) const;
  CORBA::ULong current_threads (void) const;
  void add_active (void);
  bool remove_active (bool force);

  // @}

private:

  int create_threads_i (size_t count);

  TAO_DTP_Thread_Pool_Manager &manager_;

  CORBA::ULong id_;

  /// This boolean is set when we are shutting down, then we will not create
  /// any new dynamic threads
  bool shutdown_;

  TAO_DTP_Definition definition_;
  TAO_DTP_Thread_Pool_Threads threads_;
  TAO_DTP_Termination_Waiter waiter_;

  CORBA::ULong active_count_;

  TAO_DTP_New_Leader_Generator new_thread_generator_;

  /// Lock to guard all members of the pool
  mutable TAO_SYNCH_MUTEX lock_;

  /// synchronzing new threads with the requester of threads
  TAO_SYNCH_MUTEX activation_lock_;
  TAO_SYNCH_CONDITION activation_cond_;

  /// synchronzing new threads with the requester of threads
  TAO_SYNCH_MUTEX termination_lock_;
  TAO_SYNCH_CONDITION termination_cond_;
};

/**
 * @class TAO_DTP_Thread_Pool_Manager
 *
 * @brief Class for managing thread pools.
 *
 * \nosubgrouping
 *
 **/
class TAO_Dynamic_TP_Export TAO_DTP_Thread_Pool_Manager
{
public:

  /// Constructor.
  TAO_DTP_Thread_Pool_Manager (TAO_ORB_Core &orb_core);

  /// Destructor.
  ~TAO_DTP_Thread_Pool_Manager (void);

  /// Wait for threads to exit.
  void wait (void);

  /// Create a threadpool without lanes.
  CORBA::ULong create_threadpool (TAO_DTP_Definition &def);

  /// Destroy a threadpool.
  void destroy_threadpool (CORBA::ULong threadpool);

  /// Collection of thread pools.
  typedef ACE_Hash_Map_Manager<CORBA::ULong, TAO_DTP_Thread_Pool *,
                               ACE_Null_Mutex> THREAD_POOLS;

  /// @name Accessors
  // @{
  TAO_ORB_Core &orb_core (void) const;
  // @}

private:

  /// @name Helpers
  // @{

  CORBA::ULong
  create_threadpool_i (TAO_DTP_Definition &def);

  CORBA::ULong
  create_threadpool_helper (TAO_DTP_Thread_Pool *thread_pool);
  // @}

private:

  TAO_ORB_Core &orb_core_;

  THREAD_POOLS thread_pools_;
  CORBA::ULong thread_pool_id_counter_;
  TAO_SYNCH_MUTEX lock_;
};

TAO_END_VERSIONED_NAMESPACE_DECL

#if defined (__ACE_INLINE__)
#include "tao/Dynamic_TP/DTP_Thread_Pool.inl"
#endif /* __ACE_INLINE__ */

#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */

#include /**/ "ace/post.h"

#endif /* TAO_THREAD_POOL_H */