Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / BPatch_asyncEventHandler.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
33 #ifndef __BPATCH_ASYNC_EVENT_HANDLER_H__
34 #define __BPATCH_ASYNC_EVENT_HANDLER_H__
35
36 #include <errno.h>
37 #include "os.h"
38 #include "EventHandler.h"
39 #include "process.h"
40 #include <BPatch_process.h> // for BPatch_asyncEventType
41 #include "dyninstAPI_RT/h/dyninstAPI_RT.h" // for BPatch_asyncEventRecord
42 #include "common/h/Pair.h"
43 #include "common/h/Vector.h"
44
45
46 typedef struct {
47   process *proc;
48   int fd;
49   PDSOCKET sock;
50 } process_record;
51
52 const char *asyncEventType2Str(BPatch_asyncEventType evtype); 
53
54 #ifdef DYNINST_CLASS_NAME
55 #undef DYNINST_CLASS_NAME
56 #endif
57 #define DYNINST_CLASS_NAME BPatch_asyncEventHandler
58
59 class BPatch_asyncEventHandler : public EventHandler<EventRecord> {
60         friend THREAD_RETURN asyncHandlerWrapper(void *);
61         friend class BPatch;  // only BPatch constructs & does init
62         friend class BPatch_eventMailbox;
63         public:
64         //  BPatch_asyncEventHandler::connectToProcess()
65         //  Tells the async event handler that there is a new process
66         //  to listen for.
67         bool connectToProcess(process *p);
68
69         //  BPatch_asyncEventHandler::detachFromProcess()
70         //  stop paying attention to events from specified process
71         bool detachFromProcess(process *p);
72
73         bool startupThread();
74
75     bool registerMonitoredPoint(BPatch_point *);
76
77   private: 
78     BPatch_asyncEventHandler();
79     pdvector<EventRecord> event_queue;
80     bool initialize();  //  want to catch init errors, so we do most init here
81     virtual ~BPatch_asyncEventHandler();
82         PDSOCKET setup_socket(int mutatee_pid, std::string &sock_fname);
83
84     //  BPatch_asyncEventHandler::shutDown()
85     //  Sets a flag that the async thread will check during its next iteration.
86     //  When set, the handler thread will shut itself down.
87     bool shutDown();
88
89
90     //  BPatch_asyncEventHandler::waitNextEvent()
91     //  Wait for the next event to come from a mutatee.  Essentially 
92     //  a big call to select().
93    virtual bool waitNextEvent(EventRecord &ev);
94
95     //  BPatch_asyncEventHandler::handleEvent()
96     //  called after waitNextEvent, obtains global lock and handles event.
97     //  Since event handling needs to be a locked operation (esp. if it 
98     //  requires accessing lower level dyninst data structures), this is
99     //  where it should be done.
100     virtual bool handleEvent(EventRecord &ev)
101        { __LOCK; bool ret = handleEventLocked(ev); __UNLOCK; return ret; }
102     bool handleEventLocked(EventRecord &ev);
103
104     //  BPatch_asyncEventHandler::readEvent()
105     //  Reads from the async fd connection to the mutatee
106     //static asyncReadReturnValue_t readEvent(PDSOCKET fd, void *ev, ssize_t sz);
107     static readReturnValue_t readEvent(PDSOCKET fd, EventRecord &ev);
108
109     //  BPatch_asyncEventHandler::mutateeDetach()
110     //  use oneTimeCode to call a function in the mutatee to handle
111     //  closing of the comms socket.
112
113     bool mutateeDetach(process *p);
114
115     //  BPatch_asyncEventHandler::cleanUpTerminatedProcs()
116     //  clean up any references to terminated processes in our lists
117     //  (including any user specified callbacks).
118     bool cleanUpTerminatedProcs();
119
120     //  BPatch_asyncEventHandler::cleanupProc(process *p)
121     //  remove a particular process without detaching. Used in 
122     //  exec.
123     bool cleanupProc(process *p);
124
125 #if defined (os_windows)
126     //  These vars are only modified as part of init (before/while threads are
127     //  created) so we do not need to worry about locking them:
128     PDSOCKET windows_sock;
129     unsigned int listen_port;
130 #else
131         int control_pipe_read, control_pipe_write;
132 #endif
133     bool shutDownFlag;
134
135     //  The rest:  Data in this class that is not exclusively set during init
136     //   will have to be locked.  
137     pdvector<process_record> process_fds;
138
139     dictionary_hash<Address, BPatch_point *> monitored_points;
140 };
141
142 BPatch_asyncEventHandler *getAsync();
143
144 #endif // __BPATCH_EVENT_HANDLER_H__