Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 240 lines (179 sloc) 5.375 kb
9d5b7ca migrated version_0 to trunk
blackhedd authored
1 /*****************************************************************************
2
3 $Id$
4
5 File: em.h
6 Date: 06Apr06
7
8 Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9 Gmail: blackhedd
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of either: 1) the GNU General Public License
13 as published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version; or 2) Ruby's License.
15
16 See the file COPYING for complete licensing information.
17
18 *****************************************************************************/
19
20
21
22 #ifdef OS_WIN32
23 #include "emwin.h"
24 #endif
25
26
27 // THIS ENTIRE FILE WILL EVENTUALLY BE FOR UNIX BUILDS ONLY.
28 //#ifdef OS_UNIX
29
30 #ifndef __EventMachine__H_
31 #define __EventMachine__H_
32
33 #ifdef BUILD_FOR_RUBY
34 #include <ruby.h>
35 #define EmSelect rb_thread_select
a0da1c5 @tmm1 Fix 1.9 issues with rubysig.h by checking for rb_trap_immediate
tmm1 authored
36
945eb1c @tmm1 Minor fixes for rbx compatibility
tmm1 authored
37 #if defined(HAVE_RBTRAP)
a0da1c5 @tmm1 Fix 1.9 issues with rubysig.h by checking for rb_trap_immediate
tmm1 authored
38 #include <rubysig.h>
945eb1c @tmm1 Minor fixes for rbx compatibility
tmm1 authored
39 #elif defined(HAVE_RB_THREAD_CHECK_INTS)
9ea440a @tmm1 Fix Ctrl+C and other signal handling when using kqueue/epoll
tmm1 authored
40 extern "C" {
41 void rb_enable_interrupt(void);
42 void rb_disable_interrupt(void);
43 }
44
45 #define TRAP_BEG rb_enable_interrupt()
46 #define TRAP_END do { rb_disable_interrupt(); rb_thread_check_ints(); } while(0)
945eb1c @tmm1 Minor fixes for rbx compatibility
tmm1 authored
47 #else
48 #define TRAP_BEG
49 #define TRAP_END
a0da1c5 @tmm1 Fix 1.9 issues with rubysig.h by checking for rb_trap_immediate
tmm1 authored
50 #endif
d114062 @tmm1 Enable rb_thread_blocking_region for 1.9.0 and 1.9.1
tmm1 authored
51
52 // 1.9.0 compat
eb2a882 @tmm1 Oops, 1.9.0 compat typo
tmm1 authored
53 #ifndef RUBY_UBF_IO
54 #define RUBY_UBF_IO RB_UBF_DFL
d114062 @tmm1 Enable rb_thread_blocking_region for 1.9.0 and 1.9.1
tmm1 authored
55 #endif
9d5b7ca migrated version_0 to trunk
blackhedd authored
56 #else
57 #define EmSelect select
58 #endif
59
60 class EventableDescriptor;
0259ee1 @jakedouglas Added support for monitoring of individual files using inotify and kqueu...
jakedouglas authored
61 class InotifyDescriptor;
9d5b7ca migrated version_0 to trunk
blackhedd authored
62
63
64 /********************
65 class EventMachine_t
66 ********************/
67
68 class EventMachine_t
69 {
70 public:
bc22990 @tmm1 Add EM.get_max_timers (#61)
tmm1 authored
71 static int GetMaxTimerCount();
9d5b7ca migrated version_0 to trunk
blackhedd authored
72 static void SetMaxTimerCount (int);
73
74 public:
b61b7a6 @tmm1 Define a central EMCallback type
tmm1 authored
75 EventMachine_t (EMCallback);
9d5b7ca migrated version_0 to trunk
blackhedd authored
76 virtual ~EventMachine_t();
77
78 void Run();
79 void ScheduleHalt();
80 void SignalLoopBreaker();
873ca8e @tmm1 Remove char* bindings in favor of unsigned long identifiers for connecti...
tmm1 authored
81 const unsigned long InstallOneshotTimer (int);
82 const unsigned long ConnectToServer (const char *, int, const char *, int);
83 const unsigned long ConnectToUnixServer (const char *);
84
85 const unsigned long CreateTcpServer (const char *, int);
86 const unsigned long OpenDatagramSocket (const char *, int);
87 const unsigned long CreateUnixDomainServer (const char*);
88 const unsigned long _OpenFileForWriting (const char*);
89 const unsigned long OpenKeyboard();
9d5b7ca migrated version_0 to trunk
blackhedd authored
90 //const char *Popen (const char*, const char*);
873ca8e @tmm1 Remove char* bindings in favor of unsigned long identifiers for connecti...
tmm1 authored
91 const unsigned long Socketpair (char* const*);
9d5b7ca migrated version_0 to trunk
blackhedd authored
92
93 void Add (EventableDescriptor*);
94 void Modify (EventableDescriptor*);
9baa105 @tmm1 Rename various file watching apis and variables: EM.watch_file -> EM.wat...
tmm1 authored
95
b6fc287 @tmm1 Merge branch 'master' into no_string_bindings
tmm1 authored
96 const unsigned long AttachFD (int, bool);
669b498 Applied a patch from Aman Gupta (tmm1) with contributions from
francis authored
97 int DetachFD (EventableDescriptor*);
9baa105 @tmm1 Rename various file watching apis and variables: EM.watch_file -> EM.wat...
tmm1 authored
98
9d5b7ca migrated version_0 to trunk
blackhedd authored
99 void ArmKqueueWriter (EventableDescriptor*);
100 void ArmKqueueReader (EventableDescriptor*);
101
102 void SetTimerQuantum (int);
103 static void SetuidString (const char*);
104 static int SetRlimitNofile (int);
105
ddc650a @tmm1 get_status returns a Process::Status object (#96)
tmm1 authored
106 pid_t SubprocessPid;
9d5b7ca migrated version_0 to trunk
blackhedd authored
107 int SubprocessExitStatus;
108
4af677c @jakedouglas Added EM.get_connection_count for number of current connections held by ...
jakedouglas authored
109 int GetConnectionCount();
8d39aec @jakedouglas Added getter/setter for HeartbeatInterval
jakedouglas authored
110 float GetHeartbeatInterval();
111 int SetHeartbeatInterval(float);
4af677c @jakedouglas Added EM.get_connection_count for number of current connections held by ...
jakedouglas authored
112
873ca8e @tmm1 Remove char* bindings in favor of unsigned long identifiers for connecti...
tmm1 authored
113 const unsigned long WatchFile (const char*);
9baa105 @tmm1 Rename various file watching apis and variables: EM.watch_file -> EM.wat...
tmm1 authored
114 void UnwatchFile (int);
873ca8e @tmm1 Remove char* bindings in favor of unsigned long identifiers for connecti...
tmm1 authored
115 void UnwatchFile (const unsigned long);
0259ee1 @jakedouglas Added support for monitoring of individual files using inotify and kqueu...
jakedouglas authored
116
117 #ifdef HAVE_KQUEUE
118 void _HandleKqueueFileEvent (struct kevent*);
119 void _RegisterKqueueFileEvent(int);
120 #endif
121
873ca8e @tmm1 Remove char* bindings in favor of unsigned long identifiers for connecti...
tmm1 authored
122 const unsigned long WatchPid (int);
ad5ab5a @tmm1 Simple kqueue based process watching
tmm1 authored
123 void UnwatchPid (int);
873ca8e @tmm1 Remove char* bindings in favor of unsigned long identifiers for connecti...
tmm1 authored
124 void UnwatchPid (const unsigned long);
ad5ab5a @tmm1 Simple kqueue based process watching
tmm1 authored
125
126 #ifdef HAVE_KQUEUE
127 void _HandleKqueuePidEvent (struct kevent*);
128 #endif
129
ead3098 @jakedouglas get rid of 'Int64' type and use uint64_t
jakedouglas authored
130 uint64_t GetCurrentTime() { return MyCurrentLoopTime; }
131
9d5b7ca migrated version_0 to trunk
blackhedd authored
132 // Temporary:
133 void _UseEpoll();
134 void _UseKqueue();
135
6cf5b59 @tmm1 Add EventMachine_t::UsingKqueue/Epoll getters for bKqueue and bEpoll
tmm1 authored
136 bool UsingKqueue() { return bKqueue; }
137 bool UsingEpoll() { return bEpoll; }
9d5b7ca migrated version_0 to trunk
blackhedd authored
138
d972b96 @jakedouglas refactor heartbeat mechanism
jakedouglas authored
139 void QueueHeartbeat(EventableDescriptor*);
140 void ClearHeartbeat(uint64_t);
141
142 uint64_t GetRealTime();
143
9d5b7ca migrated version_0 to trunk
blackhedd authored
144 private:
145 bool _RunOnce();
146 bool _RunTimers();
91d5dc3 @jakedouglas Changed to usec loop time on supported platforms. Cleaned up some unused...
jakedouglas authored
147 void _UpdateTime();
9d5b7ca migrated version_0 to trunk
blackhedd authored
148 void _AddNewDescriptors();
149 void _ModifyDescriptors();
150 void _InitializeLoopBreaker();
8a807c9 @jakedouglas move socket cleanup into it's own function
jakedouglas authored
151 void _CleanupSockets();
9d5b7ca migrated version_0 to trunk
blackhedd authored
152
153 bool _RunSelectOnce();
154 bool _RunEpollOnce();
155 bool _RunKqueueOnce();
156
157 void _ModifyEpollEvent (EventableDescriptor*);
d972b96 @jakedouglas refactor heartbeat mechanism
jakedouglas authored
158 void _DispatchHeartbeats();
d684cc3 @jakedouglas fix epoll thread blocking issue by calling rb_thread_select on the epoll...
jakedouglas authored
159 timeval _TimeTilNextEvent();
6996eda @jakedouglas If we get EBADF from select(), cycle through Descriptors and get rid of ...
jakedouglas authored
160 void _CleanBadDescriptors();
9d5b7ca migrated version_0 to trunk
blackhedd authored
161
162 public:
163 void _ReadLoopBreaker();
0259ee1 @jakedouglas Added support for monitoring of individual files using inotify and kqueu...
jakedouglas authored
164 void _ReadInotifyEvents();
9d5b7ca migrated version_0 to trunk
blackhedd authored
165
166 private:
167 enum {
f89dd20 @tmm1 Heap allocate struct kevent array for the Kqueue reactor
tmm1 authored
168 MaxEpollDescriptors = 64*1024,
169 MaxEvents = 4096
9d5b7ca migrated version_0 to trunk
blackhedd authored
170 };
8d39aec @jakedouglas Added getter/setter for HeartbeatInterval
jakedouglas authored
171 int HeartbeatInterval;
b61b7a6 @tmm1 Define a central EMCallback type
tmm1 authored
172 EMCallback EventCallback;
9d5b7ca migrated version_0 to trunk
blackhedd authored
173
174 class Timer_t: public Bindable_t {
175 };
176
ead3098 @jakedouglas get rid of 'Int64' type and use uint64_t
jakedouglas authored
177 multimap<uint64_t, Timer_t> Timers;
d972b96 @jakedouglas refactor heartbeat mechanism
jakedouglas authored
178 multimap<uint64_t, EventableDescriptor*> Heartbeats;
9baa105 @tmm1 Rename various file watching apis and variables: EM.watch_file -> EM.wat...
tmm1 authored
179 map<int, Bindable_t*> Files;
ad5ab5a @tmm1 Simple kqueue based process watching
tmm1 authored
180 map<int, Bindable_t*> Pids;
9d5b7ca migrated version_0 to trunk
blackhedd authored
181 vector<EventableDescriptor*> Descriptors;
182 vector<EventableDescriptor*> NewDescriptors;
183 set<EventableDescriptor*> ModifiedDescriptors;
184
ead3098 @jakedouglas get rid of 'Int64' type and use uint64_t
jakedouglas authored
185 uint64_t NextHeartbeatTime;
9d5b7ca migrated version_0 to trunk
blackhedd authored
186
187 int LoopBreakerReader;
188 int LoopBreakerWriter;
189 #ifdef OS_WIN32
190 struct sockaddr_in LoopBreakerTarget;
191 #endif
192
193 timeval Quantum;
194
ead3098 @jakedouglas get rid of 'Int64' type and use uint64_t
jakedouglas authored
195 uint64_t MyCurrentLoopTime;
196
197 #ifdef OS_WIN32
198 unsigned TickCountTickover;
199 unsigned LastTickCount;
200 #endif
201
9d5b7ca migrated version_0 to trunk
blackhedd authored
202 private:
203 bool bEpoll;
204 int epfd; // Epoll file-descriptor
1f6a4c9 @tmm1 Reduce the size of the RunEpollOnce stack frame by 800kb. This fixes the...
tmm1 authored
205 #ifdef HAVE_EPOLL
f89dd20 @tmm1 Heap allocate struct kevent array for the Kqueue reactor
tmm1 authored
206 struct epoll_event epoll_events [MaxEvents];
1f6a4c9 @tmm1 Reduce the size of the RunEpollOnce stack frame by 800kb. This fixes the...
tmm1 authored
207 #endif
9d5b7ca migrated version_0 to trunk
blackhedd authored
208
209 bool bKqueue;
210 int kqfd; // Kqueue file-descriptor
f89dd20 @tmm1 Heap allocate struct kevent array for the Kqueue reactor
tmm1 authored
211 #ifdef HAVE_KQUEUE
212 struct kevent Karray [MaxEvents];
213 #endif
0259ee1 @jakedouglas Added support for monitoring of individual files using inotify and kqueu...
jakedouglas authored
214
215 InotifyDescriptor *inotify; // pollable descriptor for our inotify instance
9d5b7ca migrated version_0 to trunk
blackhedd authored
216 };
217
218
219 /*******************
220 struct SelectData_t
221 *******************/
222
223 struct SelectData_t
224 {
225 SelectData_t();
226
227 int _Select();
228
229 int maxsocket;
230 fd_set fdreads;
231 fd_set fdwrites;
083ead4 @tmm1 Fix missing unbind event on ECONNREFUSED on win32
tmm1 authored
232 fd_set fderrors;
9d5b7ca migrated version_0 to trunk
blackhedd authored
233 timeval tv;
234 int nSockets;
235 };
236
237 #endif // __EventMachine__H_
238
239 //#endif // OS_UNIX
Something went wrong with that request. Please try again.