Problem 1:
[dyninst.git] / dyninstAPI / h / BPatch_eventLock.h
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 #ifndef _BPatch_eventLock_h_
43 #define _BPatch_eventLock_h_
44
45 #include <errno.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <assert.h>
50 #include <BPatch_dll.h>
51
52 #if defined(os_irix) || defined (os_windows)
53 #define CONST_EXPORT
54 #else
55 #define CONST_EXPORT const
56 #endif
57
58 #if defined (os_windows)
59 #define CONST_ARG
60 #else
61 #define CONST_ARG const
62 #endif
63
64 extern unsigned long primary_thread_id;
65 /*
66  * Class BPatch_eventLock
67  *
68  *
69  * This class contains a (single) mutex lock controlling access to all
70  * underlying BPatch (and lower level) data.
71  * This object is a virtual class that should be a base class for all user
72  * api's to dyninst
73  */
74
75
76 //  BPatch_eventLock
77 //  
78 //  This class forms a base class for most DyninstAPI classes and is currently
79 //  responsible for managing a global mutex variable which controls access to 
80 //  _all_ internal dyninst/paradyn data structures.
81 //
82 //  It works in conjunction with the locking macros to isolate all mutex operations,
83 //  but can be used seperately as needed (should not be necessary, think twice).
84 //
85 //  Eventually may become more specialized if we move to a finer-grain of data locking.
86
87 #define __LOCK _Lock(__FILE__, __LINE__)
88 #define __UNLOCK _Unlock(__FILE__, __LINE__)
89 #define __BROADCAST _Broadcast(__FILE__, __LINE__)
90 #define __WAIT_FOR_SIGNAL _WaitForSignal(__FILE__, __LINE__)
91
92 class eventLock;
93 extern eventLock *global_mutex;
94
95 class BPATCH_DLL_EXPORT BPatch_eventLock {
96 protected:
97
98   BPatch_eventLock(); 
99   virtual ~BPatch_eventLock();
100
101 public:
102   static eventLock *getLock() {assert(global_mutex); return global_mutex;}
103   unsigned long threadID() const;
104
105   int _Lock(const char *__file__, unsigned int __line__) const; 
106   int _Trylock(const char *__file__, unsigned int __line__) const; 
107   int _Unlock(const char *__file__, unsigned int __line__) const; 
108
109   int _Broadcast(const char *__file__, unsigned int __line__) const;
110   int _WaitForSignal(const char *__file__, unsigned int __line__) const;
111
112   unsigned int lockDepth() const;
113 };
114
115
116 #define LOCK_FUNCTION(t,x,w)     \
117                                   __LOCK; \
118                                   t ret = x w; \
119                                   __UNLOCK; \
120                                   return ret \
121
122 #define LOCK_FUNCTION_V(x,w)     \
123                                   __LOCK; \
124                                   x w; \
125                                   __UNLOCK \
126
127 //  API_EXPORT is a multithread-lock wrapper.
128 //  Argument summary:
129 //
130 //  z:  The suffix appended onto the wrapped function, usually "Int", no quotes.
131 //      The wrapped function and the wrapping function must have distinct names
132 //      or else they will not be distinguishible (type-wise) overloads.
133 //  w:  The list of arguments passed to the wrapped function.  Really just the 
134 //      argument list without type information.
135 //  t:  Return type of the function
136 //  x:  The name of the function as exported to the API user.  The "internal",
137 //      ie unlocked function prototype is constructed by appending arg <z> to this.
138 //  y:  The parameter list for the function exported to the API user.
139
140 #define API_EXPORT(z, w, t, x, y)      private:  t x##z y; \
141                                        public:   t x y \
142                                        { LOCK_FUNCTION(t, x##z, w);}
143
144 //  API_EXPORT_V is used for functions that return void.
145 //  This variant would not be necessary were (windows) vc6 not 
146 //  buggy in its template specialization code.  But here we are...
147 //  If we move to vc7, this should be re-evaluated.  The (documented)
148 //  windows compiler bugs only apply to vc6.
149
150 #define API_EXPORT_V(z, w, t, x, y)    private:  t x##z y; \
151                                        public:   t x y \
152                                        { LOCK_FUNCTION_V(x##z,w);}
153
154 //  "CTOR" and "DTOR" flavors do not have return type.
155 //  wrapped function implicitly returns void.
156
157 #define API_EXPORT_CTOR(z, w, x, y)    private:  void x##z y; \
158                                        public:   x y \
159                                        { LOCK_FUNCTION_V(x##z,w);}
160
161 //  here t is for "tilde" (ignored, but there for dtor appearance)
162
163 #define API_EXPORT_DTOR(z, w, t, x, y) private:  void x##z y; \
164                                        public:   virtual ~x y \
165                                        { LOCK_FUNCTION_V(x##z,w);}
166
167 //  operators present a special case for the preprocessor
168 //  suffix <z> is appended to the word "operator", eg, operator_lessthan
169 //  (with <z> = "_lessthan"), forms the wrapped function name
170
171 #define API_EXPORT_OPER(z, w, t, x, y) private:  t operator##z y; \
172                                        public:   t x y \
173                                        { LOCK_FUNCTION(t,operator##z,w);}
174
175
176 #endif
177