Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / h / BPatch_eventLock.h
1 /*
2  * Copyright (c) 1996-2009 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  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #ifndef _BPatch_eventLock_h_
33 #define _BPatch_eventLock_h_
34
35 #include <errno.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <assert.h>
40 #include "BPatch_dll.h"
41
42 #if defined (_MSC_VER)
43 #define CONST_EXPORT
44 #else
45 #define CONST_EXPORT const
46 #endif
47
48 #if defined (_MSC_VER)
49 #define CONST_ARG
50 #else
51 #define CONST_ARG const
52 #endif
53
54 extern unsigned long primary_thread_id;
55 /*
56  * Class BPatch_eventLock
57  *
58  *
59  * This class contains a (single) mutex lock controlling access to all
60  * underlying BPatch (and lower level) data.
61  * This object is a virtual class that should be a base class for all user
62  * api's to dyninst
63  */
64
65
66 //  BPatch_eventLock
67 //  
68 //  This class forms a base class for most DyninstAPI classes and is currently
69 //  responsible for managing a global mutex variable which controls access to 
70 //  _all_ internal dyninst/paradyn data structures.
71 //
72 //  It works in conjunction with the locking macros to isolate all mutex operations,
73 //  but can be used seperately as needed (should not be necessary, think twice).
74 //
75 //  Eventually may become more specialized if we move to a finer-grain of data locking.
76
77 #define __LOCK _Lock(__FILE__, __LINE__)
78 #define __UNLOCK _Unlock(__FILE__, __LINE__)
79 #define __BROADCAST _Broadcast(__FILE__, __LINE__)
80 #define __WAIT_FOR_SIGNAL _WaitForSignal(__FILE__, __LINE__)
81
82 class eventLock;
83 BPATCH_DLL_EXPORT int bpatch_printf(const char *format, ...);
84
85 class BPATCH_DLL_EXPORT BPatch_eventLock {
86 protected:
87
88   BPatch_eventLock(); 
89   virtual ~BPatch_eventLock();
90
91 public:
92   static eventLock *getLock();
93   unsigned long threadID() const;
94
95   int _Lock(const char *__file__, unsigned int __line__) const; 
96   int _Trylock(const char *__file__, unsigned int __line__) const; 
97   int _Unlock(const char *__file__, unsigned int __line__) const; 
98
99   int _Broadcast(const char *__file__, unsigned int __line__) const;
100   int _WaitForSignal(const char *__file__, unsigned int __line__) const;
101
102   unsigned int lockDepth() const;
103 };
104
105 #define pp2str(s) #s
106
107 #define LOCK_FUNCTION(t,x,w)     \
108   __LOCK; \
109   if (lockDepth() == 1) \
110     bpatch_printf("Calling %s %s::%s %s...\n", \
111                   #t, pp2str(DYNINST_CLASS_NAME), #x, #w); \
112   t ret = x w; \
113   if (lockDepth() == 1) \
114    bpatch_printf("  Finished call %s::%s\n", \
115                  pp2str(DYNINST_CLASS_NAME), #x); \
116   __UNLOCK; \
117   return ret
118
119 #define LOCK_FUNCTION_V(x,w)     \
120   __LOCK; \
121   if (lockDepth() == 1) \
122     bpatch_printf("Calling void %s::%s %s\n", \
123                   pp2str(DYNINST_CLASS_NAME), #x, #w); \
124   x w; \
125   if (lockDepth() == 1) \
126     bpatch_printf("  Finished call %s::%s\n", \
127                   pp2str(DYNINST_CLASS_NAME), #x); \
128   __UNLOCK
129
130 //  API_EXPORT is a multithread-lock wrapper.
131 //  Argument summary:
132 //
133 //  z:  The suffix appended onto the wrapped function, usually "Int", no quotes.
134 //      The wrapped function and the wrapping function must have distinct names
135 //      or else they will not be distinguishible (type-wise) overloads.
136 //  w:  The list of arguments passed to the wrapped function.  Really just the 
137 //      argument list without type information.
138 //  t:  Return type of the function
139 //  x:  The name of the function as exported to the API user.  The "internal",
140 //      ie unlocked function prototype is constructed by appending arg <z> to this.
141 //  y:  The parameter list for the function exported to the API user.
142
143 #define API_EXPORT(z, w, t, x, y)      private:  t x##z y; \
144                                        public:   t x y \
145                                        { LOCK_FUNCTION(t, x##z, w);}
146
147 #define API_EXPORT_VIRT(z, w, t, x, y)      private:  t x##z y; \
148                                             public:   virtual t x y \
149                                             { LOCK_FUNCTION(t, x##z, w);}
150
151 //  API_EXPORT_V is used for functions that return void.
152 //  This variant would not be necessary were (windows) vc6 not 
153 //  buggy in its template specialization code.  But here we are...
154 //  If we move to vc7, this should be re-evaluated.  The (documented)
155 //  windows compiler bugs only apply to vc6.
156
157 #define API_EXPORT_V(z, w, t, x, y)    private:  t x##z y; \
158                                        public:   t x y \
159                                        { LOCK_FUNCTION_V(x##z,w);}
160
161 //  "CTOR" and "DTOR" flavors do not have return type.
162 //  wrapped function implicitly returns void.
163
164 #define API_EXPORT_CTOR(z, w, x, y)    private:  void x##z y; \
165                                        public:   x y \
166                                        { LOCK_FUNCTION_V(x##z,w);}
167
168 //  here t is for "tilde" (ignored, but there for dtor appearance)
169
170 #define API_EXPORT_DTOR(z, w, t, x, y) private:  void x##z y; \
171                                        public:   virtual ~x y \
172                                        { LOCK_FUNCTION_V(x##z,w);}
173
174 //  operators present a special case for the preprocessor
175 //  suffix <z> is appended to the word "operator", eg, operator_lessthan
176 //  (with <z> = "_lessthan"), forms the wrapped function name
177
178 #define API_EXPORT_OPER(z, w, t, x, y) private:  t operator##z y; \
179                                        public:   t x y \
180                                        { LOCK_FUNCTION(t,operator##z,w);}
181
182
183 #endif
184