1 // -*- Mode: C++; -*-
2 //                            Package   : omniORB2
3 // tracedthread.h             Created on: 15/6/99
4 //                            Author    : David Riddoch (djr)
5 //
6 //    Copyright (C) 2010-2017 Apasphere Ltd
7 //    Copyright (C) 1996-1999 AT&T Research Cambridge
8 //
9 //    This file is part of the omniORB library.
10 //
11 //    The omniORB library is free software; you can redistribute it and/or
12 //    modify it under the terms of the GNU Lesser General Public
13 //    License as published by the Free Software Foundation; either
14 //    version 2.1 of the License, or (at your option) any later version.
15 //
16 //    This library is distributed in the hope that it will be useful,
17 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
18 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 //    Lesser General Public License for more details.
20 //
21 //    You should have received a copy of the GNU Lesser General Public
22 //    License along with this library. If not, see http://www.gnu.org/licenses/
23 //
24 //
25 // Description:
26 //    omni_thread style mutex and condition variables with checks.
27 //
28 
29 #ifndef __OMNI_TRACEDTHREAD_H__
30 #define __OMNI_TRACEDTHREAD_H__
31 
32 
33 // Lock tracing is controlled by autoconf, or in the dummy
34 // omniconfig.h.  You can override it here if you wish.
35 
36 //#define OMNIORB_ENABLE_LOCK_TRACES
37 
38 
39 //////////////////////////////////////////////////////////////////////
40 // omniORB locks and partial lock order
41 //
42 //
43 // BiDirClientRope::pd_lock
44 //   Protects bidir state in rope
45 //   Before omniTransportLock.
46 //   Before giopServer::pd_lock.
47 //
48 // corbaBoa boa_lock
49 //   Protects BOA refcount, state.
50 //   Before omni::internalLock.
51 //   Before omniObjAdapter oa_lock.
52 //
53 // corbaOrb orb_lock
54 //   Protects CORBA::ORB existence and state.
55 //   Synchronises ORB::run().
56 //   Held while calling module attach() and detach().
57 //   Before omniTransportLock.
58 //   Before omni::poRcLock.
59 //
60 // giopServer::pd_lock
61 //   Protects server state
62 //   Before omniTransportLock.
63 //   Before SocketCollection::pd_collection_lock.
64 //
65 // omni::internalLock
66 //   Protects many parts of omniORB internal state including object table.
67 //   Before omniServantActivatorTaskQueue::pd_queue_lock.
68 //   Before omni::objref_rc_lock.
69 //   Before omniIOR::lock
70 //
71 // omniServantActivatorTaskQueue::pd_task_lock
72 //   Serialises calls to ServantActivator methods.
73 //   Before omni::internalLock.
74 //   Before omniObjAdapter::sd_detachedObjectLock.
75 //   Calls into application-provided incarnate / etherealize.
76 //
77 // omniTransportLock
78 //   Protects connection state, ropes, strands.
79 //   Before SocketCollection::pd_collection_lock.
80 //
81 // omniObjAdapter oa_lock
82 //   Protects object adapters, incoming endpoints.
83 //   Before giopServer::pd_lock.
84 //
85 // omniObjAdapter::sd_detachedObjectLock
86 //   Handles count of detached objects in object adapter.
87 //   After all other locks, but caller should not hold omni::internalLock.
88 //
89 // omniOrbPOA::pd_lock
90 //   Protects POA's state.
91 //   Before omni::internalLock.
92 //   Before omni::poRcLock.
93 //
94 // poa poa_lock
95 //   Protects collection of POAs.
96 //   Before omniOrbPOA::pd_lock.
97 //   Before omniObjAdapter oa_lock.
98 //   Before poamanager pm_lock.
99 //   Before omni::poRcLock.
100 //
101 // poamanager pm_lock
102 //   Protects POAManager state.
103 //   Before omni::poRcLock.
104 //
105 // sslActiveCollection::pd_lock
106 //   Protects socket count in sslActiveCollection.
107 //   Before SocketCollection::pd_collection_lock
108 //
109 // tcpActiveCollection::pd_lock
110 //   Protects socket count in tcpActiveCollection.
111 //   Before SocketCollection::pd_collection_lock
112 //
113 // unixActiveCollection::pd_lock
114 //   Protects socket count in unixActiveCollection.
115 //   Before SocketCollection::pd_collection_lock
116 //
117 //
118 //////////////////////////////////////////////////////////////////////
119 //
120 // Locks that are after all others in the partial order. No locks are
121 // acquired while holding these; lock ordering above does not
122 // necessarily list these.
123 //
124 // anyLock
125 //   Protects pointers inside Any.
126 //
127 // ContextImpl::pd_lock
128 //   Protects Context.
129 //
130 // DynAnyImplBase::refCountLock
131 //   Protects DynAny implementation ref count and existence.
132 //
133 // giopStream::dumpbuf::lock
134 //   Ensures only one thread is dumping a buffer at a time.
135 //
136 // initRefs ba_lock
137 //   Protects bootstrap agent.
138 //
139 // initRefs sl_lock
140 //   Protects lists of initial reference services.
141 //
142 // libcWrapper rand_lock
143 //   Serialises call to rand() on platforms without rand_r().
144 //
145 // omni::objref_rc_lock
146 //   Protects normal object reference refcounts.
147 //
148 // omni::poRcLock
149 //   Pseudo object reference count lock.
150 //
151 // omniAsyncCallDescriptor::sd_lock
152 //   Protects state of async calls.
153 //
154 // omniAsyncInvoker::pd_lock
155 //   Protects invoker state.
156 //
157 // omniCompressionManager::pd_lock
158 //   Protects omniCompressionManager refcount.
159 //
160 // omniExHandlers::TableLock
161 //   Protects omniExHandlers::Table.
162 //
163 // omniInternal nil_ref_lock
164 //   Protects creation of nil objref singletons.
165 //
166 // omniIOR::lock
167 //   Protects omniIOR refcount and IORInfo pointer.
168 //
169 // omniOrbPOA::pd_main_thread_sync.mu
170 //   Used in Main Thread dispatch.
171 //
172 // omniServantActivatorTaskQueue::pd_queue_lock
173 //   Protects ServantActivator queue.
174 //
175 // orbMultiRequest::q_lock
176 //   Protects queue for multiple request handling.
177 //
178 // poa generateUniqueId lock
179 //   Protects id generation.
180 //
181 // poa RemoveRefTask::pd_mu
182 //   Used to remove servant reference from separate thread in main thread POAs.
183 //
184 // proxyObjectFactory::ofl_mutex
185 //   Protects proxyObjectFactory table.
186 //
187 // Scavenger::mutex
188 //   Protects lifetime of the connection scavenger.
189 //
190 // SocketCollection::pd_collection_lock
191 //   Protects sets of sockets.
192 //
193 // TypeCode aliasExpandedTc_lock
194 //   Protects TypeCode's alias expanded version.
195 //
196 // TypeCode::refcount_lock
197 //   Protects reference count and internal structure of TypeCodes.
198 //
199 // valueFactoryTableTracker::vf_lock
200 //   Protects valuefactory table.
201 //
202 // zlibCompressorFactory::pd_lock
203 //   Protects zlibCompressorFactory refcount.
204 //
205 // zlibCompressor::pd_lock
206 //   Protects zlibCompressor refcount.
207 //
208 
209 
210 //////////////////////////////////////////////////////////////////////
211 ////////////////////////// omni_tracedmutex //////////////////////////
212 //////////////////////////////////////////////////////////////////////
213 
214 #ifndef OMNIORB_ENABLE_LOCK_TRACES
215 
216 #define ASSERT_OMNI_TRACEDMUTEX_HELD(m, yes)
217 
218 class omni_tracedmutex : public omni_mutex {
219 public:
omni_mutex()220   inline omni_tracedmutex(const char* /*name*/=0) : omni_mutex() {}
221 };
222 
223 typedef omni_mutex_lock omni_tracedmutex_lock;
224 
225 class omni_tracedcondition : public omni_condition {
226 public:
227   inline omni_tracedcondition(omni_tracedmutex* m, const char* /*name*/=0)
omni_condition(m)228     : omni_condition(m) {}
229 };
230 
231 #else
232 
233 class omni_tracedcondition;
234 
235 
236 class omni_tracedmutex {
237 public:
238   omni_tracedmutex(const char* name=0);
239   ~omni_tracedmutex();
240 
241   void lock();
242   void unlock();
acquire(void)243   inline void acquire(void) { lock();   }
release(void)244   inline void release(void) { unlock(); }
245 
246   void assert_held(const char* file, int line, int yes);
247 
248 private:
249   friend class omni_tracedcondition;
250 
251   omni_tracedmutex(const omni_tracedmutex&);
252   omni_tracedmutex& operator=(const omni_tracedmutex&);
253 
254   omni_mutex     pd_lock;    // protects other members
255   omni_condition pd_cond;    // so can wait for mutex to unlock
256   omni_thread*   pd_holder;  // the thread holding pd_m, or 0
257   int            pd_n_conds; // number of dependent condition vars
258   int            pd_deleted; // set true on deletion, may catch later use
259   char*          pd_logname; // name to use for logging
260 };
261 
262 //////////////////////////////////////////////////////////////////////
263 //////////////////////// omni_tracedcondition ////////////////////////
264 //////////////////////////////////////////////////////////////////////
265 
266 class omni_tracedcondition {
267 public:
268   omni_tracedcondition(omni_tracedmutex* m, const char* name = 0);
269   ~omni_tracedcondition();
270 
271   void wait();
272   int timedwait(unsigned long secs, unsigned long nanosecs = 0);
timedwait(const omni_time_t & t)273   inline int timedwait(const omni_time_t& t) { return timedwait(t.s, t.ns); }
274   void signal();
275   void broadcast();
276 
277 private:
278   omni_tracedcondition(const omni_tracedcondition&);
279   omni_tracedcondition& operator=(const omni_tracedcondition&);
280 
281   omni_tracedmutex& pd_mutex;
282   omni_condition    pd_cond;
283   int               pd_n_waiters;
284   int               pd_deleted;
285   char*             pd_logname;
286 };
287 
288 //////////////////////////////////////////////////////////////////////
289 //////////////////////// omni_tracedmutex_lock ///////////////////////
290 //////////////////////////////////////////////////////////////////////
291 
292 class omni_tracedmutex_lock {
293 public:
omni_tracedmutex_lock(omni_tracedmutex & m)294   inline omni_tracedmutex_lock(omni_tracedmutex& m) :pd_m(m) { m.lock(); }
~omni_tracedmutex_lock()295   inline ~omni_tracedmutex_lock() { pd_m.unlock(); }
296 
297 private:
298   omni_tracedmutex_lock(const omni_tracedmutex_lock&);
299   omni_tracedmutex_lock& operator = (const omni_tracedmutex_lock&);
300 
301   omni_tracedmutex& pd_m;
302 };
303 
304 
305 #define ASSERT_OMNI_TRACEDMUTEX_HELD(m, yes)  \
306   (m).assert_held(__FILE__, __LINE__, (yes))
307 
308 // #ifndef OMNIORB_ENABLE_LOCK_TRACES
309 #endif
310 
311 
312 //////////////////////////////////////////////////////////////////////
313 ///////////////////////// omni_optional_lock /////////////////////////
314 //////////////////////////////////////////////////////////////////////
315 
316 class omni_optional_lock {
317 public:
omni_optional_lock(omni_tracedmutex & m,int locked,int locked_on_exit)318   inline omni_optional_lock(omni_tracedmutex& m, int locked,
319 			    int locked_on_exit)
320     : pd_locked(locked_on_exit), pd_m(m)
321     { if( !locked ) pd_m.lock(); }
322 
~omni_optional_lock()323   inline ~omni_optional_lock() { if( !pd_locked )  pd_m.unlock(); }
324 
325 private:
326   omni_optional_lock(const omni_optional_lock&);
327   omni_optional_lock& operator = (const omni_optional_lock&);
328 
329   int               pd_locked;
330   omni_tracedmutex& pd_m;
331 };
332 
333 
334 //////////////////////////////////////////////////////////////////////
335 //////////////////////// omni_tracedmutex_unlock /////////////////////
336 //////////////////////////////////////////////////////////////////////
337 
338 class omni_tracedmutex_unlock {
339 public:
omni_tracedmutex_unlock(omni_tracedmutex & m)340   inline omni_tracedmutex_unlock(omni_tracedmutex& m) : pd_m(m) { m.unlock(); }
~omni_tracedmutex_unlock()341   inline ~omni_tracedmutex_unlock() { pd_m.lock(); }
342 
343 private:
344   omni_tracedmutex_unlock(const omni_tracedmutex_unlock&);
345   omni_tracedmutex_unlock& operator=(const omni_tracedmutex_unlock&);
346 
347   omni_tracedmutex& pd_m;
348 };
349 
350 
351 #endif  // __OMNITRACEDTHREAD_H__
352