eventmachine-maglev- 1.0.0.beta.4 → 1.0.0.rc.4
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/README.md +1 -1
- data/Rakefile +11 -11
- data/eventmachine.gemspec +1 -1
- data/ext/cmain.cpp +41 -3
- data/ext/ed.cpp +31 -6
- data/ext/ed.h +9 -5
- data/ext/em.cpp +33 -10
- data/ext/em.h +11 -1
- data/ext/eventmachine.h +4 -0
- data/ext/extconf.rb +24 -5
- data/ext/fastfilereader/extconf.rb +20 -2
- data/ext/pipe.cpp +2 -2
- data/ext/project.h +3 -2
- data/ext/rubymain.cpp +108 -19
- data/ext/ssl.cpp +9 -1
- data/java/src/com/rubyeventmachine/EmReactor.java +4 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +1 -0
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +6 -0
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +6 -0
- data/lib/em/completion.rb +4 -3
- data/lib/em/connection.rb +17 -2
- data/lib/em/iterator.rb +42 -42
- data/lib/em/pool.rb +7 -2
- data/lib/em/protocols/postgres3.rb +6 -8
- data/lib/em/protocols/smtpclient.rb +28 -28
- data/lib/em/pure_ruby.rb +12 -0
- data/lib/em/threaded_resource.rb +1 -1
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +57 -11
- data/lib/jeventmachine.rb +5 -0
- data/{tasks → rakelib}/cpp.rake_example +0 -0
- data/{tasks → rakelib}/package.rake +0 -0
- data/{tasks → rakelib}/test.rake +0 -0
- data/tests/test_basic.rb +67 -0
- data/tests/test_idle_connection.rb +23 -0
- data/tests/test_pool.rb +67 -1
- data/tests/test_processes.rb +18 -0
- data/tests/test_proxy_connection.rb +13 -1
- data/tests/test_set_sock_opt.rb +37 -0
- data/tests/test_unbind_reason.rb +19 -2
- metadata +15 -13
data/README.md
CHANGED
@@ -18,7 +18,7 @@ This unique combination makes EventMachine a premier choice for designers of cri
|
|
18
18
|
applications, including Web servers and proxies, email and IM production systems, authentication/authorization
|
19
19
|
processors, and many more.
|
20
20
|
|
21
|
-
EventMachine has been around since
|
21
|
+
EventMachine has been around since the early 2000s and is a mature and battle tested library.
|
22
22
|
|
23
23
|
|
24
24
|
## What EventMachine is good for? ##
|
data/Rakefile
CHANGED
@@ -1,11 +1,6 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
|
3
|
-
import *Dir['tasks/*.rake']
|
1
|
+
require 'rubygems'
|
2
|
+
GEMSPEC = Gem::Specification.load('eventmachine.gemspec')
|
4
3
|
|
5
|
-
require File.expand_path('../lib/em/version', __FILE__)
|
6
|
-
GEMSPEC = eval(File.read(File.expand_path('../eventmachine.gemspec', __FILE__)))
|
7
|
-
|
8
|
-
require 'yard'
|
9
4
|
require 'rake/clean'
|
10
5
|
task :clobber => :clean
|
11
6
|
|
@@ -13,8 +8,13 @@ desc "Build eventmachine, then run tests."
|
|
13
8
|
task :default => [:compile, :test]
|
14
9
|
|
15
10
|
desc 'Generate documentation'
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
begin
|
12
|
+
require 'yard'
|
13
|
+
YARD::Rake::YardocTask.new do |t|
|
14
|
+
t.files = ['lib/**/*.rb', '-', 'docs/*.md']
|
15
|
+
t.options = ['--main', 'README.md', '--no-private']
|
16
|
+
t.options = ['--exclude', 'lib/jeventmachine', '--exclude', 'lib/pr_eventmachine']
|
17
|
+
end
|
18
|
+
rescue LoadError
|
19
|
+
task :yard do puts "Please install yard first!"; end
|
20
20
|
end
|
data/eventmachine.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.files = `git ls-files`.split("\n")
|
14
14
|
s.extensions = ["ext/extconf.rb", "ext/fastfilereader/extconf.rb"]
|
15
15
|
|
16
|
-
s.add_development_dependency 'rake-compiler', '0.
|
16
|
+
s.add_development_dependency 'rake-compiler', '~> 0.8.1'
|
17
17
|
s.add_development_dependency 'yard', ">= 0.7.2"
|
18
18
|
s.add_development_dependency 'bluecloth'
|
19
19
|
|
data/ext/cmain.cpp
CHANGED
@@ -220,7 +220,7 @@ evma_pause
|
|
220
220
|
|
221
221
|
extern "C" int evma_pause (const unsigned long binding)
|
222
222
|
{
|
223
|
-
|
223
|
+
EventableDescriptor *cd = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
224
224
|
if (cd)
|
225
225
|
return cd->Pause() ? 1 : 0;
|
226
226
|
|
@@ -233,7 +233,7 @@ evma_resume
|
|
233
233
|
|
234
234
|
extern "C" int evma_resume (const unsigned long binding)
|
235
235
|
{
|
236
|
-
|
236
|
+
EventableDescriptor *cd = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
237
237
|
if (cd)
|
238
238
|
return cd->Resume() ? 1 : 0;
|
239
239
|
|
@@ -246,13 +246,22 @@ evma_is_paused
|
|
246
246
|
|
247
247
|
extern "C" int evma_is_paused (const unsigned long binding)
|
248
248
|
{
|
249
|
-
|
249
|
+
EventableDescriptor *cd = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
250
250
|
if (cd)
|
251
251
|
return cd->IsPaused() ? 1 : 0;
|
252
252
|
|
253
253
|
return 0;
|
254
254
|
}
|
255
255
|
|
256
|
+
/************************
|
257
|
+
evma_num_close_scheduled
|
258
|
+
************************/
|
259
|
+
|
260
|
+
extern "C" int evma_num_close_scheduled ()
|
261
|
+
{
|
262
|
+
return EventMachine->NumCloseScheduled;
|
263
|
+
}
|
264
|
+
|
256
265
|
/**********************
|
257
266
|
evma_create_tcp_server
|
258
267
|
**********************/
|
@@ -804,6 +813,35 @@ extern "C" void evma_stop_proxy (const unsigned long from)
|
|
804
813
|
ed->StopProxy();
|
805
814
|
}
|
806
815
|
|
816
|
+
/******************
|
817
|
+
evma_proxied_bytes
|
818
|
+
*******************/
|
819
|
+
|
820
|
+
extern "C" unsigned long evma_proxied_bytes (const unsigned long from)
|
821
|
+
{
|
822
|
+
ensure_eventmachine("evma_proxied_bytes");
|
823
|
+
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
|
824
|
+
if (ed)
|
825
|
+
return ed->GetProxiedBytes();
|
826
|
+
else
|
827
|
+
return 0;
|
828
|
+
}
|
829
|
+
|
830
|
+
|
831
|
+
/***************************
|
832
|
+
evma_get_last_activity_time
|
833
|
+
****************************/
|
834
|
+
|
835
|
+
extern "C" uint64_t evma_get_last_activity_time(const unsigned long from)
|
836
|
+
{
|
837
|
+
ensure_eventmachine("evma_get_last_activity_time");
|
838
|
+
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
|
839
|
+
if (ed)
|
840
|
+
return ed->GetLastActivity();
|
841
|
+
else
|
842
|
+
return 0;
|
843
|
+
}
|
844
|
+
|
807
845
|
|
808
846
|
/***************************
|
809
847
|
evma_get_heartbeat_interval
|
data/ext/ed.cpp
CHANGED
@@ -54,16 +54,19 @@ EventableDescriptor::EventableDescriptor (int sd, EventMachine_t *em):
|
|
54
54
|
bCloseNow (false),
|
55
55
|
bCloseAfterWriting (false),
|
56
56
|
MySocket (sd),
|
57
|
+
bAttached (false),
|
57
58
|
bWatchOnly (false),
|
58
59
|
EventCallback (NULL),
|
59
60
|
bCallbackUnbind (true),
|
60
61
|
UnbindReasonCode (0),
|
61
62
|
ProxyTarget(NULL),
|
62
63
|
ProxiedFrom(NULL),
|
64
|
+
ProxiedBytes(0),
|
63
65
|
MaxOutboundBufSize(0),
|
64
66
|
MyEventMachine (em),
|
65
67
|
PendingConnectTimeout(20000000),
|
66
|
-
InactivityTimeout (0)
|
68
|
+
InactivityTimeout (0),
|
69
|
+
bPaused (false)
|
67
70
|
{
|
68
71
|
/* There are three ways to close a socket, all of which should
|
69
72
|
* automatically signal to the event machine that this object
|
@@ -114,6 +117,7 @@ EventableDescriptor::~EventableDescriptor()
|
|
114
117
|
(*EventCallback)(ProxiedFrom->GetBinding(), EM_PROXY_TARGET_UNBOUND, NULL, 0);
|
115
118
|
ProxiedFrom->StopProxy();
|
116
119
|
}
|
120
|
+
MyEventMachine->NumCloseScheduled--;
|
117
121
|
StopProxy();
|
118
122
|
Close();
|
119
123
|
}
|
@@ -168,13 +172,21 @@ void EventableDescriptor::Close()
|
|
168
172
|
* Therefore, it is necessary to notify EventMachine that
|
169
173
|
* the fd associated with this EventableDescriptor is
|
170
174
|
* closing.
|
175
|
+
*
|
176
|
+
* EventMachine also never closes fds for STDIN, STDOUT and
|
177
|
+
* STDERR (0, 1 & 2)
|
171
178
|
*/
|
172
179
|
|
173
180
|
// Close the socket right now. Intended for emergencies.
|
174
|
-
if (MySocket != INVALID_SOCKET
|
175
|
-
MyEventMachine->
|
176
|
-
|
177
|
-
close
|
181
|
+
if (MySocket != INVALID_SOCKET) {
|
182
|
+
MyEventMachine->Deregister (this);
|
183
|
+
|
184
|
+
// Do not close STDIN, STDOUT, STDERR
|
185
|
+
if (MySocket > 2 && !bAttached) {
|
186
|
+
shutdown (MySocket, 1);
|
187
|
+
close (MySocket);
|
188
|
+
}
|
189
|
+
|
178
190
|
MySocket = INVALID_SOCKET;
|
179
191
|
}
|
180
192
|
}
|
@@ -205,6 +217,7 @@ EventableDescriptor::ScheduleClose
|
|
205
217
|
|
206
218
|
void EventableDescriptor::ScheduleClose (bool after_writing)
|
207
219
|
{
|
220
|
+
MyEventMachine->NumCloseScheduled++;
|
208
221
|
// KEEP THIS SYNCHRONIZED WITH ::IsCloseScheduled.
|
209
222
|
if (after_writing)
|
210
223
|
bCloseAfterWriting = true;
|
@@ -235,6 +248,7 @@ void EventableDescriptor::StartProxy(const unsigned long to, const unsigned long
|
|
235
248
|
StopProxy();
|
236
249
|
ProxyTarget = ed;
|
237
250
|
BytesToProxy = length;
|
251
|
+
ProxiedBytes = 0;
|
238
252
|
ed->SetProxiedFrom(this, bufsize);
|
239
253
|
return;
|
240
254
|
}
|
@@ -281,6 +295,7 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
|
|
281
295
|
if (BytesToProxy > 0) {
|
282
296
|
unsigned long proxied = min(BytesToProxy, (unsigned long) size);
|
283
297
|
ProxyTarget->SendOutboundData(buf, proxied);
|
298
|
+
ProxiedBytes += (unsigned long) proxied;
|
284
299
|
BytesToProxy -= proxied;
|
285
300
|
if (BytesToProxy == 0) {
|
286
301
|
StopProxy();
|
@@ -291,6 +306,7 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
|
|
291
306
|
}
|
292
307
|
} else {
|
293
308
|
ProxyTarget->SendOutboundData(buf, size);
|
309
|
+
ProxiedBytes += (unsigned long) size;
|
294
310
|
}
|
295
311
|
} else {
|
296
312
|
(*EventCallback)(GetBinding(), EM_CONNECTION_READ, buf, size);
|
@@ -355,7 +371,6 @@ ConnectionDescriptor::ConnectionDescriptor
|
|
355
371
|
|
356
372
|
ConnectionDescriptor::ConnectionDescriptor (int sd, EventMachine_t *em):
|
357
373
|
EventableDescriptor (sd, em),
|
358
|
-
bPaused (false),
|
359
374
|
bConnectPending (false),
|
360
375
|
bNotifyReadable (false),
|
361
376
|
bNotifyWritable (false),
|
@@ -449,6 +464,16 @@ void ConnectionDescriptor::SetConnectPending(bool f)
|
|
449
464
|
}
|
450
465
|
|
451
466
|
|
467
|
+
/**********************************
|
468
|
+
ConnectionDescriptor::SetAttached
|
469
|
+
***********************************/
|
470
|
+
|
471
|
+
void ConnectionDescriptor::SetAttached(bool state)
|
472
|
+
{
|
473
|
+
bAttached = state;
|
474
|
+
}
|
475
|
+
|
476
|
+
|
452
477
|
/**********************************
|
453
478
|
ConnectionDescriptor::SetWatchOnly
|
454
479
|
***********************************/
|
data/ext/ed.h
CHANGED
@@ -79,6 +79,7 @@ class EventableDescriptor: public Bindable_t
|
|
79
79
|
virtual int SetCommInactivityTimeout (uint64_t value) {return 0;}
|
80
80
|
uint64_t GetPendingConnectTimeout();
|
81
81
|
int SetPendingConnectTimeout (uint64_t value);
|
82
|
+
uint64_t GetLastActivity() { return LastActivity; }
|
82
83
|
|
83
84
|
#ifdef HAVE_EPOLL
|
84
85
|
struct epoll_event *GetEpollEvent() { return &EpollEvent; }
|
@@ -86,11 +87,12 @@ class EventableDescriptor: public Bindable_t
|
|
86
87
|
|
87
88
|
virtual void StartProxy(const unsigned long, const unsigned long, const unsigned long);
|
88
89
|
virtual void StopProxy();
|
90
|
+
virtual unsigned long GetProxiedBytes(){ return ProxiedBytes; };
|
89
91
|
virtual void SetProxiedFrom(EventableDescriptor*, const unsigned long);
|
90
92
|
virtual int SendOutboundData(const char*,int){ return -1; }
|
91
|
-
virtual bool IsPaused(){ return
|
92
|
-
virtual bool Pause(){ return
|
93
|
-
virtual bool Resume(){
|
93
|
+
virtual bool IsPaused(){ return bPaused; }
|
94
|
+
virtual bool Pause(){ bPaused = true; return bPaused; }
|
95
|
+
virtual bool Resume(){ bPaused = false; return bPaused; }
|
94
96
|
|
95
97
|
void SetUnbindReasonCode(int code){ UnbindReasonCode = code; }
|
96
98
|
virtual int ReportErrorStatus(){ return 0; }
|
@@ -103,6 +105,7 @@ class EventableDescriptor: public Bindable_t
|
|
103
105
|
|
104
106
|
protected:
|
105
107
|
int MySocket;
|
108
|
+
bool bAttached;
|
106
109
|
bool bWatchOnly;
|
107
110
|
|
108
111
|
EMCallback EventCallback;
|
@@ -115,6 +118,7 @@ class EventableDescriptor: public Bindable_t
|
|
115
118
|
unsigned long BytesToProxy;
|
116
119
|
EventableDescriptor *ProxyTarget;
|
117
120
|
EventableDescriptor *ProxiedFrom;
|
121
|
+
unsigned long ProxiedBytes;
|
118
122
|
|
119
123
|
unsigned long MaxOutboundBufSize;
|
120
124
|
|
@@ -127,6 +131,7 @@ class EventableDescriptor: public Bindable_t
|
|
127
131
|
uint64_t InactivityTimeout;
|
128
132
|
uint64_t LastActivity;
|
129
133
|
uint64_t NextHeartbeat;
|
134
|
+
bool bPaused;
|
130
135
|
};
|
131
136
|
|
132
137
|
|
@@ -168,9 +173,9 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
168
173
|
|
169
174
|
void SetNotifyReadable (bool);
|
170
175
|
void SetNotifyWritable (bool);
|
176
|
+
void SetAttached (bool);
|
171
177
|
void SetWatchOnly (bool);
|
172
178
|
|
173
|
-
bool IsPaused(){ return bPaused; }
|
174
179
|
bool Pause();
|
175
180
|
bool Resume();
|
176
181
|
|
@@ -217,7 +222,6 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
217
222
|
};
|
218
223
|
|
219
224
|
protected:
|
220
|
-
bool bPaused;
|
221
225
|
bool bConnectPending;
|
222
226
|
|
223
227
|
bool bNotifyReadable;
|
data/ext/em.cpp
CHANGED
@@ -73,6 +73,7 @@ EventMachine_t::EventMachine_t (EMCallback event_callback):
|
|
73
73
|
NextHeartbeatTime (0),
|
74
74
|
LoopBreakerReader (-1),
|
75
75
|
LoopBreakerWriter (-1),
|
76
|
+
NumCloseScheduled (0),
|
76
77
|
bTerminateSignalReceived (false),
|
77
78
|
bEpoll (false),
|
78
79
|
epfd (-1),
|
@@ -197,10 +198,9 @@ EventMachine_t::SetTimerQuantum
|
|
197
198
|
void EventMachine_t::SetTimerQuantum (int interval)
|
198
199
|
{
|
199
200
|
/* We get a timer-quantum expressed in milliseconds.
|
200
|
-
* Don't set a quantum smaller than 5 or larger than 2500.
|
201
201
|
*/
|
202
202
|
|
203
|
-
if ((interval < 5) || (interval >
|
203
|
+
if ((interval < 5) || (interval > 5*60*1000))
|
204
204
|
throw std::runtime_error ("invalid timer-quantum");
|
205
205
|
|
206
206
|
Quantum.tv_sec = interval / 1000;
|
@@ -673,7 +673,13 @@ EventMachine_t::_TimeTilNextEvent
|
|
673
673
|
|
674
674
|
timeval EventMachine_t::_TimeTilNextEvent()
|
675
675
|
{
|
676
|
+
// 29jul11: Changed calculation base from MyCurrentLoopTime to the
|
677
|
+
// real time. As MyCurrentLoopTime is set at the beginning of an
|
678
|
+
// iteration and this calculation is done at the end, evenmachine
|
679
|
+
// will potentially oversleep by the amount of time the iteration
|
680
|
+
// took to execute.
|
676
681
|
uint64_t next_event = 0;
|
682
|
+
uint64_t current_time = GetRealTime();
|
677
683
|
|
678
684
|
if (!Heartbeats.empty()) {
|
679
685
|
multimap<uint64_t,EventableDescriptor*>::iterator heartbeats = Heartbeats.begin();
|
@@ -687,16 +693,16 @@ timeval EventMachine_t::_TimeTilNextEvent()
|
|
687
693
|
}
|
688
694
|
|
689
695
|
if (!NewDescriptors.empty() || !ModifiedDescriptors.empty()) {
|
690
|
-
next_event =
|
696
|
+
next_event = current_time;
|
691
697
|
}
|
692
|
-
|
698
|
+
|
693
699
|
timeval tv;
|
694
700
|
|
695
|
-
if (next_event == 0) {
|
701
|
+
if (next_event == 0 || NumCloseScheduled > 0) {
|
696
702
|
tv = Quantum;
|
697
703
|
} else {
|
698
|
-
if (next_event >
|
699
|
-
uint64_t duration = next_event -
|
704
|
+
if (next_event > current_time) {
|
705
|
+
uint64_t duration = next_event - current_time;
|
700
706
|
tv.tv_sec = duration / 1000000;
|
701
707
|
tv.tv_usec = duration % 1000000;
|
702
708
|
} else {
|
@@ -1257,7 +1263,7 @@ const unsigned long EventMachine_t::ConnectToUnixServer (const char *server)
|
|
1257
1263
|
|
1258
1264
|
#ifdef OS_WIN32
|
1259
1265
|
throw std::runtime_error ("unix-domain connection unavailable on this platform");
|
1260
|
-
return
|
1266
|
+
return 0;
|
1261
1267
|
#endif
|
1262
1268
|
|
1263
1269
|
// The whole rest of this function is only compiled on Unix systems.
|
@@ -1356,6 +1362,7 @@ const unsigned long EventMachine_t::AttachFD (int fd, bool watch_mode)
|
|
1356
1362
|
if (!cd)
|
1357
1363
|
throw std::runtime_error ("no connection allocated");
|
1358
1364
|
|
1365
|
+
cd->SetAttached(true);
|
1359
1366
|
cd->SetWatchOnly(watch_mode);
|
1360
1367
|
cd->SetConnectPending (false);
|
1361
1368
|
|
@@ -1395,7 +1402,11 @@ int EventMachine_t::DetachFD (EventableDescriptor *ed)
|
|
1395
1402
|
if (bKqueue) {
|
1396
1403
|
// remove any read/write events for this fd
|
1397
1404
|
struct kevent k;
|
1405
|
+
#ifdef __NetBSD__
|
1406
|
+
EV_SET (&k, ed->GetSocket(), EVFILT_READ | EVFILT_WRITE, EV_DELETE, 0, 0, (intptr_t)ed);
|
1407
|
+
#else
|
1398
1408
|
EV_SET (&k, ed->GetSocket(), EVFILT_READ | EVFILT_WRITE, EV_DELETE, 0, 0, ed);
|
1409
|
+
#endif
|
1399
1410
|
int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
|
1400
1411
|
if (t < 0 && (errno != ENOENT) && (errno != EBADF)) {
|
1401
1412
|
char buf [200];
|
@@ -1651,7 +1662,11 @@ void EventMachine_t::ArmKqueueWriter (EventableDescriptor *ed)
|
|
1651
1662
|
if (!ed)
|
1652
1663
|
throw std::runtime_error ("added bad descriptor");
|
1653
1664
|
struct kevent k;
|
1665
|
+
#ifdef __NetBSD__
|
1666
|
+
EV_SET (&k, ed->GetSocket(), EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, (intptr_t)ed);
|
1667
|
+
#else
|
1654
1668
|
EV_SET (&k, ed->GetSocket(), EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, ed);
|
1669
|
+
#endif
|
1655
1670
|
int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
|
1656
1671
|
if (t < 0) {
|
1657
1672
|
char buf [200];
|
@@ -1673,7 +1688,11 @@ void EventMachine_t::ArmKqueueReader (EventableDescriptor *ed)
|
|
1673
1688
|
if (!ed)
|
1674
1689
|
throw std::runtime_error ("added bad descriptor");
|
1675
1690
|
struct kevent k;
|
1691
|
+
#ifdef __NetBSD__
|
1692
|
+
EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, (intptr_t)ed);
|
1693
|
+
#else
|
1676
1694
|
EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, ed);
|
1695
|
+
#endif
|
1677
1696
|
int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
|
1678
1697
|
if (t < 0) {
|
1679
1698
|
char buf [200];
|
@@ -1724,7 +1743,11 @@ void EventMachine_t::_AddNewDescriptors()
|
|
1724
1743
|
// INCOMPLETE. Some descriptors don't want to be readable.
|
1725
1744
|
assert (kqfd != -1);
|
1726
1745
|
struct kevent k;
|
1746
|
+
#ifdef __NetBSD__
|
1747
|
+
EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, (intptr_t)ed);
|
1748
|
+
#else
|
1727
1749
|
EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, ed);
|
1750
|
+
#endif
|
1728
1751
|
int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
|
1729
1752
|
assert (t == 0);
|
1730
1753
|
}
|
@@ -1789,10 +1812,10 @@ void EventMachine_t::Modify (EventableDescriptor *ed)
|
|
1789
1812
|
|
1790
1813
|
|
1791
1814
|
/***********************
|
1792
|
-
EventMachine_t::
|
1815
|
+
EventMachine_t::Deregister
|
1793
1816
|
***********************/
|
1794
1817
|
|
1795
|
-
void EventMachine_t::
|
1818
|
+
void EventMachine_t::Deregister (EventableDescriptor *ed)
|
1796
1819
|
{
|
1797
1820
|
if (!ed)
|
1798
1821
|
throw std::runtime_error ("modified bad descriptor");
|
data/ext/em.h
CHANGED
@@ -46,6 +46,15 @@ See the file COPYING for complete licensing information.
|
|
46
46
|
#ifndef RUBY_UBF_IO
|
47
47
|
#define RUBY_UBF_IO RB_UBF_DFL
|
48
48
|
#endif
|
49
|
+
#ifndef RSTRING_PTR
|
50
|
+
#define RSTRING_PTR(str) RSTRING(str)->ptr
|
51
|
+
#endif
|
52
|
+
#ifndef RSTRING_LEN
|
53
|
+
#define RSTRING_LEN(str) RSTRING(str)->len
|
54
|
+
#endif
|
55
|
+
#ifndef RSTRING_LENINT
|
56
|
+
#define RSTRING_LENINT(str) RSTRING_LEN(str)
|
57
|
+
#endif
|
49
58
|
#else
|
50
59
|
#define EmSelect select
|
51
60
|
#endif
|
@@ -84,7 +93,7 @@ class EventMachine_t
|
|
84
93
|
|
85
94
|
void Add (EventableDescriptor*);
|
86
95
|
void Modify (EventableDescriptor*);
|
87
|
-
void
|
96
|
+
void Deregister (EventableDescriptor*);
|
88
97
|
|
89
98
|
const unsigned long AttachFD (int, bool);
|
90
99
|
int DetachFD (EventableDescriptor*);
|
@@ -155,6 +164,7 @@ class EventMachine_t
|
|
155
164
|
public:
|
156
165
|
void _ReadLoopBreaker();
|
157
166
|
void _ReadInotifyEvents();
|
167
|
+
int NumCloseScheduled;
|
158
168
|
|
159
169
|
private:
|
160
170
|
enum {
|
data/ext/eventmachine.h
CHANGED
@@ -59,6 +59,8 @@ extern "C" {
|
|
59
59
|
int evma_is_paused(const unsigned long binding);
|
60
60
|
int evma_resume(const unsigned long binding);
|
61
61
|
|
62
|
+
int evma_num_close_scheduled();
|
63
|
+
|
62
64
|
void evma_stop_tcp_server (const unsigned long signature);
|
63
65
|
const unsigned long evma_create_tcp_server (const char *address, int port);
|
64
66
|
const unsigned long evma_create_unix_domain_server (const char *filename);
|
@@ -84,6 +86,7 @@ extern "C" {
|
|
84
86
|
float evma_get_pending_connect_timeout (const unsigned long binding);
|
85
87
|
int evma_set_pending_connect_timeout (const unsigned long binding, float value);
|
86
88
|
int evma_get_outbound_data_size (const unsigned long binding);
|
89
|
+
uint64_t evma_get_last_activity_time (const unsigned long);
|
87
90
|
int evma_send_file_data_to_connection (const unsigned long binding, const char *filename);
|
88
91
|
|
89
92
|
void evma_close_connection (const unsigned long binding, int after_writing);
|
@@ -107,6 +110,7 @@ extern "C" {
|
|
107
110
|
|
108
111
|
void evma_start_proxy(const unsigned long, const unsigned long, const unsigned long, const unsigned long);
|
109
112
|
void evma_stop_proxy(const unsigned long);
|
113
|
+
unsigned long evma_proxied_bytes(const unsigned long);
|
110
114
|
|
111
115
|
int evma_set_rlimit_nofile (int n_files);
|
112
116
|
|
data/ext/extconf.rb
CHANGED
@@ -25,7 +25,7 @@ end
|
|
25
25
|
def manual_ssl_config
|
26
26
|
ssl_libs_heads_args = {
|
27
27
|
:unix => [%w[ssl crypto], %w[openssl/ssl.h openssl/err.h]],
|
28
|
-
:mswin => [%w[ssleay32
|
28
|
+
:mswin => [%w[ssleay32 eay32], %w[openssl/ssl.h openssl/err.h]],
|
29
29
|
}
|
30
30
|
|
31
31
|
dc_flags = ['ssl']
|
@@ -40,7 +40,8 @@ def manual_ssl_config
|
|
40
40
|
end
|
41
41
|
|
42
42
|
if ENV['CROSS_COMPILING']
|
43
|
-
|
43
|
+
openssl_version = ENV.fetch("OPENSSL_VERSION", "1.0.0j")
|
44
|
+
openssl_dir = File.expand_path("~/.rake-compiler/builds/openssl-#{openssl_version}/")
|
44
45
|
if File.exists?(openssl_dir)
|
45
46
|
FileUtils.mkdir_p Dir.pwd+"/openssl/"
|
46
47
|
FileUtils.cp Dir[openssl_dir+"/include/openssl/*.h"], Dir.pwd+"/openssl/", :verbose => true
|
@@ -57,7 +58,7 @@ if ENV['CROSS_COMPILING']
|
|
57
58
|
end
|
58
59
|
|
59
60
|
# Try to use pkg_config first, fixes #73
|
60
|
-
if pkg_config('openssl') || manual_ssl_config
|
61
|
+
if (!ENV['CROSS_COMPILING'] and pkg_config('openssl')) || manual_ssl_config
|
61
62
|
add_define "WITH_SSL"
|
62
63
|
else
|
63
64
|
add_define "WITHOUT_SSL"
|
@@ -80,7 +81,7 @@ if defined? RUBY_ENGINE and RUBY_ENGINE =~ /maglev/
|
|
80
81
|
end
|
81
82
|
|
82
83
|
if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
|
83
|
-
GNU_CHAIN = $1 == 'mingw'
|
84
|
+
GNU_CHAIN = ENV['CROSS_COMPILING'] or $1 == 'mingw'
|
84
85
|
OS_WIN32 = true
|
85
86
|
add_define "OS_WIN32"
|
86
87
|
else
|
@@ -91,6 +92,15 @@ else
|
|
91
92
|
add_define "HAVE_KQUEUE" if have_header("sys/event.h") and have_header("sys/queue.h")
|
92
93
|
end
|
93
94
|
|
95
|
+
# Adjust number of file descriptors (FD) on Windows
|
96
|
+
|
97
|
+
if RbConfig::CONFIG["host_os"] =~ /mingw/
|
98
|
+
found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS").
|
99
|
+
any? { |v| v.include?("FD_SETSIZE") }
|
100
|
+
|
101
|
+
add_define "FD_SETSIZE=32767" unless found
|
102
|
+
end
|
103
|
+
|
94
104
|
# Main platform invariances:
|
95
105
|
|
96
106
|
case RUBY_PLATFORM
|
@@ -143,6 +153,15 @@ when /linux/
|
|
143
153
|
when /aix/
|
144
154
|
CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G -Wl,-brtl"
|
145
155
|
|
156
|
+
when /cygwin/
|
157
|
+
# For rubies built with Cygwin, CXX may be set to CC, which is just
|
158
|
+
# a wrapper for gcc.
|
159
|
+
# This will compile, but it will not link to the C++ std library.
|
160
|
+
# Explicitly set CXX to use g++.
|
161
|
+
CONFIG['CXX'] = "g++"
|
162
|
+
# on Unix we need a g++ link, not gcc.
|
163
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
164
|
+
|
146
165
|
else
|
147
166
|
# on Unix we need a g++ link, not gcc.
|
148
167
|
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
@@ -158,4 +177,4 @@ add_define 'HAVE_MAKE_PAIR' if try_link(<<SRC, '-lstdc++')
|
|
158
177
|
SRC
|
159
178
|
TRY_LINK.sub!('$(CXX)', '$(CC)')
|
160
179
|
|
161
|
-
create_makefile "rubyeventmachine"
|
180
|
+
create_makefile "rubyeventmachine"
|
@@ -17,7 +17,7 @@ add_define 'BUILD_FOR_RUBY'
|
|
17
17
|
# Minor platform details between *nix and Windows:
|
18
18
|
|
19
19
|
if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
|
20
|
-
GNU_CHAIN = $1 == 'mingw'
|
20
|
+
GNU_CHAIN = ENV['CROSS_COMPILING'] or $1 == 'mingw'
|
21
21
|
OS_WIN32 = true
|
22
22
|
add_define "OS_WIN32"
|
23
23
|
else
|
@@ -26,6 +26,15 @@ else
|
|
26
26
|
add_define 'OS_UNIX'
|
27
27
|
end
|
28
28
|
|
29
|
+
# Adjust number of file descriptors (FD) on Windows
|
30
|
+
|
31
|
+
if RbConfig::CONFIG["host_os"] =~ /mingw/
|
32
|
+
found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS").
|
33
|
+
any? { |v| v.include?("FD_SETSIZE") }
|
34
|
+
|
35
|
+
add_define "FD_SETSIZE=32767" unless found
|
36
|
+
end
|
37
|
+
|
29
38
|
# Main platform invariances:
|
30
39
|
|
31
40
|
case RUBY_PLATFORM
|
@@ -77,9 +86,18 @@ when /aix/
|
|
77
86
|
# on Unix we need a g++ link, not gcc.
|
78
87
|
CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G"
|
79
88
|
|
89
|
+
when /cygwin/
|
90
|
+
# For rubies built with Cygwin, CXX may be set to CC, which is just
|
91
|
+
# a wrapper for gcc.
|
92
|
+
# This will compile, but it will not link to the C++ std library.
|
93
|
+
# Explicitly set CXX to use g++.
|
94
|
+
CONFIG['CXX'] = "g++"
|
95
|
+
# on Unix we need a g++ link, not gcc.
|
96
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
97
|
+
|
80
98
|
else
|
81
99
|
# on Unix we need a g++ link, not gcc.
|
82
100
|
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
83
101
|
end
|
84
102
|
|
85
|
-
create_makefile "fastfilereaderext"
|
103
|
+
create_makefile "fastfilereaderext"
|
data/ext/pipe.cpp
CHANGED
@@ -282,7 +282,7 @@ bool PipeDescriptor::SelectForRead()
|
|
282
282
|
* a pending state, so this is simpler than for the
|
283
283
|
* ConnectionDescriptor object.
|
284
284
|
*/
|
285
|
-
return true;
|
285
|
+
return bPaused ? false : true;
|
286
286
|
}
|
287
287
|
|
288
288
|
/******************************
|
@@ -295,7 +295,7 @@ bool PipeDescriptor::SelectForWrite()
|
|
295
295
|
* a pending state, so this is simpler than for the
|
296
296
|
* ConnectionDescriptor object.
|
297
297
|
*/
|
298
|
-
return (GetOutboundDataSize() > 0);
|
298
|
+
return (GetOutboundDataSize() > 0) && !bPaused ? true : false;
|
299
299
|
}
|
300
300
|
|
301
301
|
|
data/ext/project.h
CHANGED
@@ -82,7 +82,8 @@ typedef int SOCKET;
|
|
82
82
|
|
83
83
|
#ifdef OS_WIN32
|
84
84
|
// 21Sep09: windows limits select() to 64 sockets by default, we increase it to 1024 here (before including winsock2.h)
|
85
|
-
|
85
|
+
// 18Jun12: fd_setsize must be changed in the ruby binary (not in this extension). redefining it also causes segvs, see eventmachine/eventmachine#333
|
86
|
+
//#define FD_SETSIZE 1024
|
86
87
|
|
87
88
|
#define WIN32_LEAN_AND_MEAN
|
88
89
|
#include <windows.h>
|
@@ -96,7 +97,7 @@ typedef int socklen_t;
|
|
96
97
|
typedef int pid_t;
|
97
98
|
#endif
|
98
99
|
|
99
|
-
#if !defined(_MSC_VER) || _MSC_VER >
|
100
|
+
#if !defined(_MSC_VER) || _MSC_VER > 1500
|
100
101
|
#include <stdint.h>
|
101
102
|
#endif
|
102
103
|
|