MattHulse-eventmachine 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +14 -0
- data/README +82 -0
- data/Rakefile +279 -0
- data/docs/COPYING +60 -0
- data/docs/ChangeLog +211 -0
- data/docs/DEFERRABLES +133 -0
- data/docs/EPOLL +141 -0
- data/docs/GNU +281 -0
- data/docs/INSTALL +13 -0
- data/docs/KEYBOARD +38 -0
- data/docs/LEGAL +25 -0
- data/docs/LIGHTWEIGHT_CONCURRENCY +70 -0
- data/docs/PURE_RUBY +75 -0
- data/docs/RELEASE_NOTES +94 -0
- data/docs/SMTP +2 -0
- data/docs/SPAWNED_PROCESSES +89 -0
- data/docs/TODO +8 -0
- data/eventmachine.gemspec +41 -0
- data/examples/ex_channel.rb +43 -0
- data/examples/ex_queue.rb +2 -0
- data/examples/helper.rb +2 -0
- data/ext/binder.cpp +125 -0
- data/ext/binder.h +46 -0
- data/ext/cmain.cpp +821 -0
- data/ext/cplusplus.cpp +202 -0
- data/ext/ed.cpp +1868 -0
- data/ext/ed.h +416 -0
- data/ext/em.cpp +2270 -0
- data/ext/em.h +228 -0
- data/ext/emwin.cpp +300 -0
- data/ext/emwin.h +94 -0
- data/ext/epoll.cpp +26 -0
- data/ext/epoll.h +25 -0
- data/ext/eventmachine.h +122 -0
- data/ext/eventmachine_cpp.h +96 -0
- data/ext/extconf.rb +138 -0
- data/ext/fastfilereader/extconf.rb +84 -0
- data/ext/fastfilereader/mapper.cpp +214 -0
- data/ext/fastfilereader/mapper.h +59 -0
- data/ext/fastfilereader/rubymain.cpp +127 -0
- data/ext/files.cpp +94 -0
- data/ext/files.h +65 -0
- data/ext/kb.cpp +81 -0
- data/ext/page.cpp +107 -0
- data/ext/page.h +51 -0
- data/ext/pipe.cpp +349 -0
- data/ext/project.h +147 -0
- data/ext/rubymain.cpp +1152 -0
- data/ext/sigs.cpp +89 -0
- data/ext/sigs.h +32 -0
- data/ext/ssl.cpp +460 -0
- data/ext/ssl.h +94 -0
- data/java/.classpath +8 -0
- data/java/.project +17 -0
- data/java/src/com/rubyeventmachine/Application.java +192 -0
- data/java/src/com/rubyeventmachine/Connection.java +74 -0
- data/java/src/com/rubyeventmachine/ConnectionFactory.java +37 -0
- data/java/src/com/rubyeventmachine/DefaultConnectionFactory.java +46 -0
- data/java/src/com/rubyeventmachine/EmReactor.java +557 -0
- data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +69 -0
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +189 -0
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +364 -0
- data/java/src/com/rubyeventmachine/PeriodicTimer.java +38 -0
- data/java/src/com/rubyeventmachine/Timer.java +54 -0
- data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +108 -0
- data/java/src/com/rubyeventmachine/tests/ConnectTest.java +146 -0
- data/java/src/com/rubyeventmachine/tests/EMTest.java +80 -0
- data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +53 -0
- data/java/src/com/rubyeventmachine/tests/TestServers.java +74 -0
- data/java/src/com/rubyeventmachine/tests/TestTimers.java +89 -0
- data/lib/em/buftok.rb +138 -0
- data/lib/em/callback.rb +26 -0
- data/lib/em/channel.rb +57 -0
- data/lib/em/connection.rb +564 -0
- data/lib/em/deferrable.rb +187 -0
- data/lib/em/file_watch.rb +54 -0
- data/lib/em/future.rb +61 -0
- data/lib/em/messages.rb +66 -0
- data/lib/em/process_watch.rb +44 -0
- data/lib/em/processes.rb +119 -0
- data/lib/em/protocols.rb +35 -0
- data/lib/em/protocols/header_and_content.rb +138 -0
- data/lib/em/protocols/httpclient.rb +263 -0
- data/lib/em/protocols/httpclient2.rb +582 -0
- data/lib/em/protocols/line_and_text.rb +126 -0
- data/lib/em/protocols/linetext2.rb +160 -0
- data/lib/em/protocols/memcache.rb +323 -0
- data/lib/em/protocols/object_protocol.rb +45 -0
- data/lib/em/protocols/postgres3.rb +247 -0
- data/lib/em/protocols/saslauth.rb +175 -0
- data/lib/em/protocols/smtpclient.rb +350 -0
- data/lib/em/protocols/smtpserver.rb +547 -0
- data/lib/em/protocols/stomp.rb +200 -0
- data/lib/em/protocols/tcptest.rb +53 -0
- data/lib/em/queue.rb +61 -0
- data/lib/em/spawnable.rb +85 -0
- data/lib/em/streamer.rb +130 -0
- data/lib/em/timers.rb +55 -0
- data/lib/em/version.rb +3 -0
- data/lib/eventmachine.rb +1698 -0
- data/lib/evma.rb +32 -0
- data/lib/evma/callback.rb +32 -0
- data/lib/evma/container.rb +75 -0
- data/lib/evma/factory.rb +77 -0
- data/lib/evma/protocol.rb +87 -0
- data/lib/evma/reactor.rb +48 -0
- data/lib/jeventmachine.rb +246 -0
- data/lib/pr_eventmachine.rb +1022 -0
- data/setup.rb +1585 -0
- data/tasks/cpp.rake +77 -0
- data/tasks/project.rake +79 -0
- data/tasks/tests.rake +193 -0
- data/tests/client.crt +31 -0
- data/tests/client.key +51 -0
- data/tests/test_attach.rb +126 -0
- data/tests/test_basic.rb +284 -0
- data/tests/test_channel.rb +63 -0
- data/tests/test_connection_count.rb +35 -0
- data/tests/test_defer.rb +47 -0
- data/tests/test_epoll.rb +160 -0
- data/tests/test_error_handler.rb +35 -0
- data/tests/test_errors.rb +82 -0
- data/tests/test_exc.rb +55 -0
- data/tests/test_file_watch.rb +49 -0
- data/tests/test_futures.rb +198 -0
- data/tests/test_handler_check.rb +37 -0
- data/tests/test_hc.rb +218 -0
- data/tests/test_httpclient.rb +218 -0
- data/tests/test_httpclient2.rb +153 -0
- data/tests/test_inactivity_timeout.rb +50 -0
- data/tests/test_kb.rb +60 -0
- data/tests/test_ltp.rb +182 -0
- data/tests/test_ltp2.rb +317 -0
- data/tests/test_next_tick.rb +133 -0
- data/tests/test_object_protocol.rb +37 -0
- data/tests/test_process_watch.rb +48 -0
- data/tests/test_processes.rb +128 -0
- data/tests/test_proxy_connection.rb +92 -0
- data/tests/test_pure.rb +125 -0
- data/tests/test_queue.rb +44 -0
- data/tests/test_running.rb +42 -0
- data/tests/test_sasl.rb +72 -0
- data/tests/test_send_file.rb +242 -0
- data/tests/test_servers.rb +76 -0
- data/tests/test_smtpclient.rb +83 -0
- data/tests/test_smtpserver.rb +85 -0
- data/tests/test_spawn.rb +322 -0
- data/tests/test_ssl_args.rb +68 -0
- data/tests/test_ssl_methods.rb +50 -0
- data/tests/test_ssl_verify.rb +82 -0
- data/tests/test_timers.rb +162 -0
- data/tests/test_ud.rb +36 -0
- data/tests/testem.rb +31 -0
- data/web/whatis +7 -0
- metadata +223 -0
data/ext/em.h
ADDED
@@ -0,0 +1,228 @@
|
|
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
|
36
|
+
|
37
|
+
#ifdef HAVE_RBTRAP
|
38
|
+
#include <rubysig.h>
|
39
|
+
#else
|
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)
|
47
|
+
#endif
|
48
|
+
|
49
|
+
// 1.9.0 compat
|
50
|
+
#ifndef RUBY_UBF_IO
|
51
|
+
#define RUBY_UBF_IO RB_UBF_DFL
|
52
|
+
#endif
|
53
|
+
#else
|
54
|
+
#define EmSelect select
|
55
|
+
#endif
|
56
|
+
|
57
|
+
|
58
|
+
#ifdef OS_UNIX
|
59
|
+
typedef long long Int64;
|
60
|
+
#endif
|
61
|
+
#ifdef OS_WIN32
|
62
|
+
typedef __int64 Int64;
|
63
|
+
#endif
|
64
|
+
|
65
|
+
extern Int64 gCurrentLoopTime;
|
66
|
+
|
67
|
+
class EventableDescriptor;
|
68
|
+
class InotifyDescriptor;
|
69
|
+
|
70
|
+
|
71
|
+
/********************
|
72
|
+
class EventMachine_t
|
73
|
+
********************/
|
74
|
+
|
75
|
+
class EventMachine_t
|
76
|
+
{
|
77
|
+
public:
|
78
|
+
static int GetMaxTimerCount();
|
79
|
+
static void SetMaxTimerCount (int);
|
80
|
+
|
81
|
+
public:
|
82
|
+
EventMachine_t (void(*event_callback)(const unsigned long, int, const char*, const unsigned long));
|
83
|
+
virtual ~EventMachine_t();
|
84
|
+
|
85
|
+
void Run();
|
86
|
+
void ScheduleHalt();
|
87
|
+
void SignalLoopBreaker();
|
88
|
+
const unsigned long InstallOneshotTimer (int);
|
89
|
+
const unsigned long ConnectToServer (const char *, int, const char *, int);
|
90
|
+
const unsigned long ConnectToUnixServer (const char *);
|
91
|
+
|
92
|
+
const unsigned long CreateTcpServer (const char *, int);
|
93
|
+
const unsigned long OpenDatagramSocket (const char *, int);
|
94
|
+
const unsigned long CreateUnixDomainServer (const char*);
|
95
|
+
const unsigned long _OpenFileForWriting (const char*);
|
96
|
+
const unsigned long OpenKeyboard();
|
97
|
+
//const char *Popen (const char*, const char*);
|
98
|
+
const unsigned long Socketpair (char* const*);
|
99
|
+
|
100
|
+
void Add (EventableDescriptor*);
|
101
|
+
void Modify (EventableDescriptor*);
|
102
|
+
|
103
|
+
const unsigned long AttachFD (int, bool);
|
104
|
+
int DetachFD (EventableDescriptor*);
|
105
|
+
|
106
|
+
void ArmKqueueWriter (EventableDescriptor*);
|
107
|
+
void ArmKqueueReader (EventableDescriptor*);
|
108
|
+
|
109
|
+
void SetTimerQuantum (int);
|
110
|
+
static void SetuidString (const char*);
|
111
|
+
static int SetRlimitNofile (int);
|
112
|
+
|
113
|
+
pid_t SubprocessPid;
|
114
|
+
int SubprocessExitStatus;
|
115
|
+
|
116
|
+
int GetConnectionCount();
|
117
|
+
float GetHeartbeatInterval();
|
118
|
+
int SetHeartbeatInterval(float);
|
119
|
+
|
120
|
+
const unsigned long WatchFile (const char*);
|
121
|
+
void UnwatchFile (int);
|
122
|
+
void UnwatchFile (const unsigned long);
|
123
|
+
|
124
|
+
#ifdef HAVE_KQUEUE
|
125
|
+
void _HandleKqueueFileEvent (struct kevent*);
|
126
|
+
void _RegisterKqueueFileEvent(int);
|
127
|
+
#endif
|
128
|
+
|
129
|
+
const unsigned long WatchPid (int);
|
130
|
+
void UnwatchPid (int);
|
131
|
+
void UnwatchPid (const unsigned long);
|
132
|
+
|
133
|
+
#ifdef HAVE_KQUEUE
|
134
|
+
void _HandleKqueuePidEvent (struct kevent*);
|
135
|
+
#endif
|
136
|
+
|
137
|
+
// Temporary:
|
138
|
+
void _UseEpoll();
|
139
|
+
void _UseKqueue();
|
140
|
+
|
141
|
+
bool UsingKqueue() { return bKqueue; }
|
142
|
+
bool UsingEpoll() { return bEpoll; }
|
143
|
+
|
144
|
+
private:
|
145
|
+
bool _RunOnce();
|
146
|
+
bool _RunTimers();
|
147
|
+
void _UpdateTime();
|
148
|
+
void _AddNewDescriptors();
|
149
|
+
void _ModifyDescriptors();
|
150
|
+
void _InitializeLoopBreaker();
|
151
|
+
|
152
|
+
bool _RunSelectOnce();
|
153
|
+
bool _RunEpollOnce();
|
154
|
+
bool _RunKqueueOnce();
|
155
|
+
|
156
|
+
void _ModifyEpollEvent (EventableDescriptor*);
|
157
|
+
|
158
|
+
public:
|
159
|
+
void _ReadLoopBreaker();
|
160
|
+
void _ReadInotifyEvents();
|
161
|
+
|
162
|
+
private:
|
163
|
+
enum {
|
164
|
+
MaxEpollDescriptors = 64*1024,
|
165
|
+
MaxEvents = 4096
|
166
|
+
};
|
167
|
+
int HeartbeatInterval;
|
168
|
+
void (*EventCallback)(const unsigned long, int, const char*, const unsigned long);
|
169
|
+
|
170
|
+
class Timer_t: public Bindable_t {
|
171
|
+
};
|
172
|
+
|
173
|
+
multimap<Int64, Timer_t> Timers;
|
174
|
+
map<int, Bindable_t*> Files;
|
175
|
+
map<int, Bindable_t*> Pids;
|
176
|
+
vector<EventableDescriptor*> Descriptors;
|
177
|
+
vector<EventableDescriptor*> NewDescriptors;
|
178
|
+
set<EventableDescriptor*> ModifiedDescriptors;
|
179
|
+
|
180
|
+
Int64 NextHeartbeatTime;
|
181
|
+
|
182
|
+
int LoopBreakerReader;
|
183
|
+
int LoopBreakerWriter;
|
184
|
+
#ifdef OS_WIN32
|
185
|
+
struct sockaddr_in LoopBreakerTarget;
|
186
|
+
#endif
|
187
|
+
|
188
|
+
timeval Quantum;
|
189
|
+
|
190
|
+
private:
|
191
|
+
bool bEpoll;
|
192
|
+
int epfd; // Epoll file-descriptor
|
193
|
+
#ifdef HAVE_EPOLL
|
194
|
+
struct epoll_event epoll_events [MaxEvents];
|
195
|
+
#endif
|
196
|
+
|
197
|
+
bool bKqueue;
|
198
|
+
int kqfd; // Kqueue file-descriptor
|
199
|
+
#ifdef HAVE_KQUEUE
|
200
|
+
struct kevent Karray [MaxEvents];
|
201
|
+
#endif
|
202
|
+
|
203
|
+
InotifyDescriptor *inotify; // pollable descriptor for our inotify instance
|
204
|
+
};
|
205
|
+
|
206
|
+
|
207
|
+
/*******************
|
208
|
+
struct SelectData_t
|
209
|
+
*******************/
|
210
|
+
|
211
|
+
struct SelectData_t
|
212
|
+
{
|
213
|
+
SelectData_t();
|
214
|
+
|
215
|
+
int _Select();
|
216
|
+
|
217
|
+
int maxsocket;
|
218
|
+
fd_set fdreads;
|
219
|
+
fd_set fdwrites;
|
220
|
+
timeval tv;
|
221
|
+
int nSockets;
|
222
|
+
};
|
223
|
+
|
224
|
+
|
225
|
+
|
226
|
+
#endif // __EventMachine__H_
|
227
|
+
|
228
|
+
//#endif // OS_UNIX
|
data/ext/emwin.cpp
ADDED
@@ -0,0 +1,300 @@
|
|
1
|
+
/*****************************************************************************
|
2
|
+
|
3
|
+
$Id$
|
4
|
+
|
5
|
+
File: emwin.cpp
|
6
|
+
Date: 05May06
|
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
|
+
// THIS ENTIRE FILE IS FOR WINDOWS BUILDS ONLY
|
22
|
+
// INCOMPLETE AND DISABLED FOR NOW.
|
23
|
+
#ifdef xOS_WIN32
|
24
|
+
|
25
|
+
#include "project.h"
|
26
|
+
|
27
|
+
|
28
|
+
// Keep a global variable floating around
|
29
|
+
// with the current loop time as set by the Event Machine.
|
30
|
+
// This avoids the need for frequent expensive calls to time(NULL);
|
31
|
+
time_t gCurrentLoopTime;
|
32
|
+
|
33
|
+
|
34
|
+
/******************************
|
35
|
+
EventMachine_t::EventMachine_t
|
36
|
+
******************************/
|
37
|
+
|
38
|
+
EventMachine_t::EventMachine_t (void (*event_callback)(const char*, int, const char*, int)):
|
39
|
+
EventCallback (event_callback),
|
40
|
+
NextHeartbeatTime (0)
|
41
|
+
{
|
42
|
+
gTerminateSignalReceived = false;
|
43
|
+
Iocp = NULL;
|
44
|
+
}
|
45
|
+
|
46
|
+
|
47
|
+
/*******************************
|
48
|
+
EventMachine_t::~EventMachine_t
|
49
|
+
*******************************/
|
50
|
+
|
51
|
+
EventMachine_t::~EventMachine_t()
|
52
|
+
{
|
53
|
+
cerr << "EM __dt\n";
|
54
|
+
if (Iocp)
|
55
|
+
CloseHandle (Iocp);
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
/****************************
|
60
|
+
EventMachine_t::ScheduleHalt
|
61
|
+
****************************/
|
62
|
+
|
63
|
+
void EventMachine_t::ScheduleHalt()
|
64
|
+
{
|
65
|
+
/* This is how we stop the machine.
|
66
|
+
* This can be called by clients. Signal handlers will probably
|
67
|
+
* set the global flag.
|
68
|
+
* For now this means there can only be one EventMachine ever running at a time.
|
69
|
+
*/
|
70
|
+
gTerminateSignalReceived = true;
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
/*******************
|
76
|
+
EventMachine_t::Run
|
77
|
+
*******************/
|
78
|
+
|
79
|
+
void EventMachine_t::Run()
|
80
|
+
{
|
81
|
+
HookControlC (true);
|
82
|
+
|
83
|
+
Iocp = CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL, 0, 0);
|
84
|
+
if (Iocp == NULL)
|
85
|
+
throw std::runtime_error ("no completion port");
|
86
|
+
|
87
|
+
|
88
|
+
DWORD nBytes, nCompletionKey;
|
89
|
+
LPOVERLAPPED Overlapped;
|
90
|
+
|
91
|
+
do {
|
92
|
+
gCurrentLoopTime = time(NULL);
|
93
|
+
// Have some kind of strategy that will dequeue maybe up to 10 completions
|
94
|
+
// without running the timers as long as they are available immediately.
|
95
|
+
// Otherwise in a busy server we're calling them every time through the loop.
|
96
|
+
if (!_RunTimers())
|
97
|
+
break;
|
98
|
+
if (GetQueuedCompletionStatus (Iocp, &nBytes, &nCompletionKey, &Overlapped, 1000)) {
|
99
|
+
}
|
100
|
+
cerr << "+";
|
101
|
+
} while (!gTerminateSignalReceived);
|
102
|
+
|
103
|
+
|
104
|
+
/*
|
105
|
+
while (true) {
|
106
|
+
gCurrentLoopTime = time(NULL);
|
107
|
+
if (!_RunTimers())
|
108
|
+
break;
|
109
|
+
_AddNewDescriptors();
|
110
|
+
if (!_RunOnce())
|
111
|
+
break;
|
112
|
+
if (gTerminateSignalReceived)
|
113
|
+
break;
|
114
|
+
}
|
115
|
+
*/
|
116
|
+
|
117
|
+
HookControlC (false);
|
118
|
+
}
|
119
|
+
|
120
|
+
|
121
|
+
/**************************
|
122
|
+
EventMachine_t::_RunTimers
|
123
|
+
**************************/
|
124
|
+
|
125
|
+
bool EventMachine_t::_RunTimers()
|
126
|
+
{
|
127
|
+
// These are caller-defined timer handlers.
|
128
|
+
// Return T/F to indicate whether we should continue the main loop.
|
129
|
+
// We rely on the fact that multimaps sort by their keys to avoid
|
130
|
+
// inspecting the whole list every time we come here.
|
131
|
+
// Just keep inspecting and processing the list head until we hit
|
132
|
+
// one that hasn't expired yet.
|
133
|
+
|
134
|
+
while (true) {
|
135
|
+
multimap<time_t,Timer_t>::iterator i = Timers.begin();
|
136
|
+
if (i == Timers.end())
|
137
|
+
break;
|
138
|
+
if (i->first > gCurrentLoopTime)
|
139
|
+
break;
|
140
|
+
if (EventCallback)
|
141
|
+
(*EventCallback) (NULL, EM_TIMER_FIRED, NULL, i->second.GetBinding());
|
142
|
+
Timers.erase (i);
|
143
|
+
}
|
144
|
+
return true;
|
145
|
+
}
|
146
|
+
|
147
|
+
|
148
|
+
/***********************************
|
149
|
+
EventMachine_t::InstallOneshotTimer
|
150
|
+
***********************************/
|
151
|
+
|
152
|
+
const char *EventMachine_t::InstallOneshotTimer (int seconds)
|
153
|
+
{
|
154
|
+
if (Timers.size() > MaxOutstandingTimers)
|
155
|
+
return false;
|
156
|
+
// Don't use the global loop-time variable here, because we might
|
157
|
+
// get called before the main event machine is running.
|
158
|
+
|
159
|
+
Timer_t t;
|
160
|
+
Timers.insert (make_pair (time(NULL) + seconds, t));
|
161
|
+
return t.GetBinding();
|
162
|
+
}
|
163
|
+
|
164
|
+
|
165
|
+
/**********************************
|
166
|
+
EventMachine_t::OpenDatagramSocket
|
167
|
+
**********************************/
|
168
|
+
|
169
|
+
const char *EventMachine_t::OpenDatagramSocket (const char *address, int port)
|
170
|
+
{
|
171
|
+
cerr << "OPEN DATAGRAM SOCKET\n";
|
172
|
+
return "Unimplemented";
|
173
|
+
}
|
174
|
+
|
175
|
+
|
176
|
+
/*******************************
|
177
|
+
EventMachine_t::CreateTcpServer
|
178
|
+
*******************************/
|
179
|
+
|
180
|
+
const char *EventMachine_t::CreateTcpServer (const char *server, int port)
|
181
|
+
{
|
182
|
+
/* Create a TCP-acceptor (server) socket and add it to the event machine.
|
183
|
+
* Return the binding of the new acceptor to the caller.
|
184
|
+
* This binding will be referenced when the new acceptor sends events
|
185
|
+
* to indicate accepted connections.
|
186
|
+
*/
|
187
|
+
|
188
|
+
const char *output_binding = NULL;
|
189
|
+
|
190
|
+
struct sockaddr_in sin;
|
191
|
+
|
192
|
+
SOCKET sd_accept = socket (AF_INET, SOCK_STREAM, 0);
|
193
|
+
if (sd_accept == INVALID_SOCKET) {
|
194
|
+
goto fail;
|
195
|
+
}
|
196
|
+
|
197
|
+
memset (&sin, 0, sizeof(sin));
|
198
|
+
sin.sin_family = AF_INET;
|
199
|
+
sin.sin_addr.s_addr = INADDR_ANY;
|
200
|
+
sin.sin_port = htons (port);
|
201
|
+
|
202
|
+
if (server && *server) {
|
203
|
+
sin.sin_addr.s_addr = inet_addr (server);
|
204
|
+
if (sin.sin_addr.s_addr == INADDR_NONE) {
|
205
|
+
hostent *hp = gethostbyname (server);
|
206
|
+
if (hp == NULL) {
|
207
|
+
//__warning ("hostname not resolved: ", server);
|
208
|
+
goto fail;
|
209
|
+
}
|
210
|
+
sin.sin_addr.s_addr = ((in_addr*)(hp->h_addr))->s_addr;
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
|
215
|
+
// No need to set reuseaddr on Windows.
|
216
|
+
|
217
|
+
|
218
|
+
if (bind (sd_accept, (struct sockaddr*)&sin, sizeof(sin))) {
|
219
|
+
//__warning ("binding failed");
|
220
|
+
goto fail;
|
221
|
+
}
|
222
|
+
|
223
|
+
if (listen (sd_accept, 100)) {
|
224
|
+
//__warning ("listen failed");
|
225
|
+
goto fail;
|
226
|
+
}
|
227
|
+
|
228
|
+
{ // Looking good.
|
229
|
+
AcceptorDescriptor *ad = new AcceptorDescriptor (this, sd_accept);
|
230
|
+
if (!ad)
|
231
|
+
throw std::runtime_error ("unable to allocate acceptor");
|
232
|
+
Add (ad);
|
233
|
+
output_binding = ad->GetBinding();
|
234
|
+
|
235
|
+
CreateIoCompletionPort ((HANDLE)sd_accept, Iocp, NULL, 0);
|
236
|
+
SOCKET sd = socket (AF_INET, SOCK_STREAM, 0);
|
237
|
+
CreateIoCompletionPort ((HANDLE)sd, Iocp, NULL, 0);
|
238
|
+
AcceptEx (sd_accept, sd,
|
239
|
+
}
|
240
|
+
|
241
|
+
return output_binding;
|
242
|
+
|
243
|
+
fail:
|
244
|
+
if (sd_accept != INVALID_SOCKET)
|
245
|
+
closesocket (sd_accept);
|
246
|
+
return NULL;
|
247
|
+
}
|
248
|
+
|
249
|
+
|
250
|
+
/*******************************
|
251
|
+
EventMachine_t::ConnectToServer
|
252
|
+
*******************************/
|
253
|
+
|
254
|
+
const char *EventMachine_t::ConnectToServer (const char *server, int port)
|
255
|
+
{
|
256
|
+
if (!server || !*server || !port)
|
257
|
+
return NULL;
|
258
|
+
|
259
|
+
sockaddr_in pin;
|
260
|
+
unsigned long HostAddr;
|
261
|
+
|
262
|
+
HostAddr = inet_addr (server);
|
263
|
+
if (HostAddr == INADDR_NONE) {
|
264
|
+
hostent *hp = gethostbyname (server);
|
265
|
+
if (!hp)
|
266
|
+
return NULL;
|
267
|
+
HostAddr = ((in_addr*)(hp->h_addr))->s_addr;
|
268
|
+
}
|
269
|
+
|
270
|
+
memset (&pin, 0, sizeof(pin));
|
271
|
+
pin.sin_family = AF_INET;
|
272
|
+
pin.sin_addr.s_addr = HostAddr;
|
273
|
+
pin.sin_port = htons (port);
|
274
|
+
|
275
|
+
int sd = socket (AF_INET, SOCK_STREAM, 0);
|
276
|
+
if (sd == INVALID_SOCKET)
|
277
|
+
return NULL;
|
278
|
+
|
279
|
+
|
280
|
+
LPOVERLAPPED olap = (LPOVERLAPPED) calloc (1, sizeof (OVERLAPPED));
|
281
|
+
cerr << "I'm dying now\n";
|
282
|
+
throw runtime_error ("UNIMPLEMENTED!!!\n");
|
283
|
+
|
284
|
+
}
|
285
|
+
|
286
|
+
|
287
|
+
|
288
|
+
/*******************
|
289
|
+
EventMachine_t::Add
|
290
|
+
*******************/
|
291
|
+
|
292
|
+
void EventMachine_t::Add (EventableDescriptor *ed)
|
293
|
+
{
|
294
|
+
cerr << "ADD\n";
|
295
|
+
}
|
296
|
+
|
297
|
+
|
298
|
+
|
299
|
+
#endif // OS_WIN32
|
300
|
+
|