Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / mailbox.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 #ifndef __EVENT_MAILBOX_H__
32 #define __EVENT_MAILBOX_H__
33 #include "os.h"
34 #include "EventHandler.h"
35 //#include "BPatch_process.h"
36 //#include "BPatch.h"
37 #include "common/h/Vector.h"
38 #include "common/h/Dictionary.h"
39
40 class BPatch_eventLock;
41 class DebuggerInterface;
42 class DBIEvent;
43
44 class eventLock {
45   friend class BPatch_eventLock;
46   friend class DebuggerInterface;
47
48   public:
49
50   eventLock();
51   virtual ~eventLock();
52
53   public:
54   unsigned int depth() {return lock_depth;}
55   int _Lock(const char *__file__, unsigned int __line__);
56   int _Trylock(const char *__file__, unsigned int __line__);
57   int _Unlock(const char *__file__, unsigned int __line__);
58   int _Broadcast(const char *__file__, unsigned int __line__);
59   int _WaitForSignal(const char *__file__, unsigned int __line__);
60
61   void printLockStack();
62
63   private:
64
65   EventLock_t mutex;
66   EventCond_t cond;
67
68   unsigned int lock_depth;
69
70   typedef struct {
71     const char *file;
72     unsigned int line;
73   } lock_stack_elem;
74
75   inline lock_stack_elem popLockStack() {
76     lock_stack_elem el = lock_stack[lock_stack.size() -1];
77     lock_stack.pop_back();
78     lock_depth--;
79     return el;
80   }
81
82   inline void pushLockStack(lock_stack_elem elm) {
83     lock_stack.push_back(elm);
84     lock_depth++;
85   }
86
87   pdvector<lock_stack_elem> lock_stack;
88   unsigned long owner_id;
89
90 #if defined (os_windows)
91   EventLock_t waiter_lock;
92   int num_waiters;
93
94   int generation_num;
95   int release_num;
96 #endif
97 };
98
99
100 class BPatch_asyncEventHandler;
101 class SignalHandler;
102
103 class CallbackBase;
104 typedef void (*CallbackCompletionCallback)(CallbackBase *);
105
106 class CallbackBase
107 {
108   public:
109     CallbackBase(unsigned long target = (unsigned long) -1L, 
110                  CallbackCompletionCallback cb = NULL) 
111                  : target_thread (target),
112                    exec_flag(false),
113                    ok_to_delete(true),
114                    cleanup_callback(cb) {}
115     virtual ~CallbackBase() {}
116     virtual bool execute()=0;
117     virtual CallbackBase *copy()=0;
118     unsigned long targetThread() {return target_thread;}
119     unsigned long execThread() {return execution_thread;}
120     void setTargetThread(unsigned long t) {target_thread = t;}
121     bool isExecuting() {return exec_flag;}
122
123     void setExecuting(bool flag = true, 
124                       unsigned long exec_thread_id = (unsigned long) -1L) {
125       execution_thread = exec_thread_id;
126       exec_flag = flag;
127     }
128     
129     void enableDelete(bool flag = true) {ok_to_delete = flag;}
130     bool deleteEnabled() {return ok_to_delete;}
131
132     CallbackCompletionCallback getCleanupCallback() {return cleanup_callback;}
133   private:
134     unsigned long target_thread;
135     unsigned long execution_thread;
136     bool exec_flag;
137     bool ok_to_delete;
138     CallbackCompletionCallback cleanup_callback;
139 };
140
141 class ThreadMailbox
142 {
143   public:
144
145     ThreadMailbox() {}
146     ~ThreadMailbox(); 
147
148      void executeOrRegisterCallback(CallbackBase *cb); 
149      void executeCallbacks(const char *file, unsigned int line); 
150      CallbackBase *runningInsideCallback();
151
152   private:
153
154     CallbackBase *executeCallback(CallbackBase *cb);
155     void cleanUpCalled();
156     pdvector<CallbackBase *> cbs;
157     pdvector<CallbackBase *> running;
158     pdvector<CallbackBase *> called;
159     eventLock mb_lock;
160 };
161
162 ThreadMailbox *getMailbox();
163
164 #define TARGET_ANY_THREAD (unsigned long) -1L
165 #define TARGET_UI_THREAD  primary_thread_id
166 #define TARGET_DBI_THREAD  dbi_thread_id
167 #define TARGET_SYNC_THREAD  sync_thread_id
168
169
170 #endif