eventmachine 1.0.0.beta.2-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. data/.gitignore +16 -0
  2. data/Gemfile +1 -0
  3. data/README +81 -0
  4. data/Rakefile +11 -0
  5. data/docs/COPYING +60 -0
  6. data/docs/ChangeLog +211 -0
  7. data/docs/DEFERRABLES +246 -0
  8. data/docs/EPOLL +141 -0
  9. data/docs/GNU +281 -0
  10. data/docs/INSTALL +13 -0
  11. data/docs/KEYBOARD +42 -0
  12. data/docs/LEGAL +25 -0
  13. data/docs/LIGHTWEIGHT_CONCURRENCY +130 -0
  14. data/docs/PURE_RUBY +75 -0
  15. data/docs/RELEASE_NOTES +94 -0
  16. data/docs/SMTP +4 -0
  17. data/docs/SPAWNED_PROCESSES +148 -0
  18. data/docs/TODO +8 -0
  19. data/eventmachine.gemspec +33 -0
  20. data/examples/ex_channel.rb +43 -0
  21. data/examples/ex_queue.rb +2 -0
  22. data/examples/ex_tick_loop_array.rb +15 -0
  23. data/examples/ex_tick_loop_counter.rb +32 -0
  24. data/examples/helper.rb +2 -0
  25. data/ext/binder.cpp +124 -0
  26. data/ext/binder.h +46 -0
  27. data/ext/cmain.cpp +838 -0
  28. data/ext/ed.cpp +1884 -0
  29. data/ext/ed.h +418 -0
  30. data/ext/em.cpp +2348 -0
  31. data/ext/em.h +228 -0
  32. data/ext/eventmachine.h +123 -0
  33. data/ext/extconf.rb +157 -0
  34. data/ext/fastfilereader/extconf.rb +85 -0
  35. data/ext/fastfilereader/mapper.cpp +214 -0
  36. data/ext/fastfilereader/mapper.h +59 -0
  37. data/ext/fastfilereader/rubymain.cpp +127 -0
  38. data/ext/kb.cpp +79 -0
  39. data/ext/page.cpp +107 -0
  40. data/ext/page.h +51 -0
  41. data/ext/pipe.cpp +347 -0
  42. data/ext/project.h +155 -0
  43. data/ext/rubymain.cpp +1200 -0
  44. data/ext/ssl.cpp +460 -0
  45. data/ext/ssl.h +94 -0
  46. data/java/.classpath +8 -0
  47. data/java/.project +17 -0
  48. data/java/src/com/rubyeventmachine/EmReactor.java +571 -0
  49. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  50. data/java/src/com/rubyeventmachine/EventableChannel.java +69 -0
  51. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +189 -0
  52. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +364 -0
  53. data/lib/em/buftok.rb +138 -0
  54. data/lib/em/callback.rb +26 -0
  55. data/lib/em/channel.rb +57 -0
  56. data/lib/em/connection.rb +569 -0
  57. data/lib/em/deferrable.rb +206 -0
  58. data/lib/em/file_watch.rb +54 -0
  59. data/lib/em/future.rb +61 -0
  60. data/lib/em/iterator.rb +270 -0
  61. data/lib/em/messages.rb +66 -0
  62. data/lib/em/process_watch.rb +44 -0
  63. data/lib/em/processes.rb +119 -0
  64. data/lib/em/protocols.rb +36 -0
  65. data/lib/em/protocols/header_and_content.rb +138 -0
  66. data/lib/em/protocols/httpclient.rb +268 -0
  67. data/lib/em/protocols/httpclient2.rb +590 -0
  68. data/lib/em/protocols/line_and_text.rb +125 -0
  69. data/lib/em/protocols/line_protocol.rb +28 -0
  70. data/lib/em/protocols/linetext2.rb +161 -0
  71. data/lib/em/protocols/memcache.rb +323 -0
  72. data/lib/em/protocols/object_protocol.rb +45 -0
  73. data/lib/em/protocols/postgres3.rb +247 -0
  74. data/lib/em/protocols/saslauth.rb +175 -0
  75. data/lib/em/protocols/smtpclient.rb +357 -0
  76. data/lib/em/protocols/smtpserver.rb +640 -0
  77. data/lib/em/protocols/socks4.rb +66 -0
  78. data/lib/em/protocols/stomp.rb +200 -0
  79. data/lib/em/protocols/tcptest.rb +53 -0
  80. data/lib/em/pure_ruby.rb +1013 -0
  81. data/lib/em/queue.rb +62 -0
  82. data/lib/em/spawnable.rb +85 -0
  83. data/lib/em/streamer.rb +130 -0
  84. data/lib/em/tick_loop.rb +85 -0
  85. data/lib/em/timers.rb +57 -0
  86. data/lib/em/version.rb +3 -0
  87. data/lib/eventmachine.rb +1548 -0
  88. data/lib/jeventmachine.rb +258 -0
  89. data/lib/rubyeventmachine.rb +2 -0
  90. data/setup.rb +1585 -0
  91. data/tasks/cpp.rake_example +77 -0
  92. data/tasks/doc.rake +30 -0
  93. data/tasks/package.rake +85 -0
  94. data/tasks/test.rake +6 -0
  95. data/tests/client.crt +31 -0
  96. data/tests/client.key +51 -0
  97. data/tests/test_attach.rb +136 -0
  98. data/tests/test_basic.rb +249 -0
  99. data/tests/test_channel.rb +64 -0
  100. data/tests/test_connection_count.rb +35 -0
  101. data/tests/test_defer.rb +49 -0
  102. data/tests/test_deferrable.rb +35 -0
  103. data/tests/test_epoll.rb +160 -0
  104. data/tests/test_error_handler.rb +35 -0
  105. data/tests/test_errors.rb +82 -0
  106. data/tests/test_exc.rb +55 -0
  107. data/tests/test_file_watch.rb +49 -0
  108. data/tests/test_futures.rb +198 -0
  109. data/tests/test_get_sock_opt.rb +30 -0
  110. data/tests/test_handler_check.rb +37 -0
  111. data/tests/test_hc.rb +190 -0
  112. data/tests/test_httpclient.rb +227 -0
  113. data/tests/test_httpclient2.rb +154 -0
  114. data/tests/test_inactivity_timeout.rb +50 -0
  115. data/tests/test_kb.rb +60 -0
  116. data/tests/test_ltp.rb +190 -0
  117. data/tests/test_ltp2.rb +317 -0
  118. data/tests/test_next_tick.rb +133 -0
  119. data/tests/test_object_protocol.rb +37 -0
  120. data/tests/test_pause.rb +70 -0
  121. data/tests/test_pending_connect_timeout.rb +48 -0
  122. data/tests/test_process_watch.rb +50 -0
  123. data/tests/test_processes.rb +128 -0
  124. data/tests/test_proxy_connection.rb +144 -0
  125. data/tests/test_pure.rb +134 -0
  126. data/tests/test_queue.rb +44 -0
  127. data/tests/test_running.rb +42 -0
  128. data/tests/test_sasl.rb +72 -0
  129. data/tests/test_send_file.rb +251 -0
  130. data/tests/test_servers.rb +76 -0
  131. data/tests/test_smtpclient.rb +83 -0
  132. data/tests/test_smtpserver.rb +85 -0
  133. data/tests/test_spawn.rb +322 -0
  134. data/tests/test_ssl_args.rb +79 -0
  135. data/tests/test_ssl_methods.rb +50 -0
  136. data/tests/test_ssl_verify.rb +82 -0
  137. data/tests/test_tick_loop.rb +59 -0
  138. data/tests/test_timers.rb +160 -0
  139. data/tests/test_ud.rb +36 -0
  140. data/tests/testem.rb +31 -0
  141. metadata +240 -0
@@ -0,0 +1,8 @@
1
+ TODO List:
2
+
3
+ 12Aug06: Noticed by Don Stocks. A TCP connect-request that results
4
+ in a failed DNS resolution fires a fatal error back to user code.
5
+ Uuuuuugly. We should probably cause an unbind event to get fired
6
+ instead, and add some parameterization so the caller can detect
7
+ the nature of the failure.
8
+
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/em/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.date = "2010-11-13"
6
+
7
+ s.name = 'eventmachine'
8
+ s.version = EventMachine::VERSION
9
+ s.homepage = 'http://rubyeventmachine.com'
10
+ s.rubyforge_project = 'eventmachine'
11
+
12
+ s.authors = ["Francis Cianfrocca", "Aman Gupta"]
13
+ s.email = ["garbagecat10@gmail.com", "aman@tmm1.net"]
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.extensions = ["ext/extconf.rb", "ext/fastfilereader/extconf.rb"]
17
+
18
+ s.add_development_dependency 'rake-compiler'
19
+
20
+ s.summary = 'Ruby/EventMachine library'
21
+ s.description = "EventMachine implements a fast, single-threaded engine for arbitrary network
22
+ communications. It's extremely easy to use in Ruby. EventMachine wraps all
23
+ interactions with IP sockets, allowing programs to concentrate on the
24
+ implementation of network protocols. It can be used to create both network
25
+ servers and clients. To create a server or client, a Ruby program only needs
26
+ to specify the IP address and port, and provide a Module that implements the
27
+ communications protocol. Implementations of several standard network protocols
28
+ are provided with the package, primarily to serve as examples. The real goal
29
+ of EventMachine is to enable programs to easily interface with other programs
30
+ using TCP/IP, especially if custom protocols are required."
31
+
32
+ s.rdoc_options = ["--title", "EventMachine", "--main", "README", "-x", "lib/em/version", "-x", "lib/jeventmachine"]
33
+ end
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ EM.run do
4
+
5
+ # Create a channel to push data to, this could be stocks...
6
+ RandChannel = EM::Channel.new
7
+
8
+ # The server simply subscribes client connections to the channel on connect,
9
+ # and unsubscribes them on disconnect.
10
+ class Server < EM::Connection
11
+ def self.start(host = '127.0.0.1', port = 8000)
12
+ EM.start_server(host, port, self)
13
+ end
14
+
15
+ def post_init
16
+ @sid = RandChannel.subscribe { |m| send_data "#{m.inspect}\n" }
17
+ end
18
+
19
+ def unbind
20
+ RandChannel.unsubscribe @sid
21
+ end
22
+ end
23
+ Server.start
24
+
25
+ # Two client connections, that just print what they receive.
26
+ 2.times do
27
+ EM.connect('127.0.0.1', 8000) do |c|
28
+ c.extend EM::P::LineText2
29
+ def c.receive_line(line)
30
+ puts "Subscriber: #{signature} got #{line}"
31
+ end
32
+ EM.add_timer(2) { c.close_connection }
33
+ end
34
+ end
35
+
36
+ # This part of the example is more fake, but imagine sleep was in fact a
37
+ # long running calculation to achieve the value.
38
+ 40.times do
39
+ EM.defer lambda { v = sleep(rand * 2); RandChannel << [Time.now, v] }
40
+ end
41
+
42
+ EM.add_timer(5) { EM.stop }
43
+ end
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ EM.run do
4
+ array = (1..100).to_a
5
+
6
+ tickloop = EM.tick_loop do
7
+ if array.empty?
8
+ :stop
9
+ else
10
+ puts array.shift
11
+ end
12
+ end
13
+
14
+ tickloop.on_stop { EM.stop }
15
+ end
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TickCounter
4
+ attr_reader :start_time, :count
5
+
6
+ def initialize
7
+ reset
8
+ @tick_loop = EM.tick_loop(method(:tick))
9
+ end
10
+
11
+ def reset
12
+ @count = 0
13
+ @start_time = EM.current_time
14
+ end
15
+
16
+ def tick
17
+ @count += 1
18
+ end
19
+
20
+ def rate
21
+ @count / (EM.current_time - @start_time)
22
+ end
23
+ end
24
+
25
+ period = 5
26
+ EM.run do
27
+ counter = TickCounter.new
28
+ EM.add_periodic_timer(period) do
29
+ puts "Ticks per second: #{counter.rate} (mean of last #{period}s)"
30
+ counter.reset
31
+ end
32
+ end
@@ -0,0 +1,2 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
2
+ require 'eventmachine'
@@ -0,0 +1,124 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: binder.cpp
6
+ Date: 07Apr06
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
+ #include "project.h"
21
+
22
+ #define DEV_URANDOM "/dev/urandom"
23
+
24
+
25
+ map<unsigned long, Bindable_t*> Bindable_t::BindingBag;
26
+
27
+
28
+ /********************************
29
+ STATIC Bindable_t::CreateBinding
30
+ ********************************/
31
+
32
+ unsigned long Bindable_t::CreateBinding()
33
+ {
34
+ static unsigned long num = 0;
35
+ while(BindingBag[++num]);
36
+ return num;
37
+ }
38
+
39
+ #if 0
40
+ string Bindable_t::CreateBinding()
41
+ {
42
+ static int index = 0;
43
+ static string seed;
44
+
45
+ if ((index >= 1000000) || (seed.length() == 0)) {
46
+ #ifdef OS_UNIX
47
+ int fd = open (DEV_URANDOM, O_RDONLY);
48
+ if (fd < 0)
49
+ throw std::runtime_error ("No entropy device");
50
+
51
+ unsigned char u[16];
52
+ size_t r = read (fd, u, sizeof(u));
53
+ if (r < sizeof(u))
54
+ throw std::runtime_error ("Unable to read entropy device");
55
+
56
+ unsigned char *u1 = (unsigned char*)u;
57
+ char u2 [sizeof(u) * 2 + 1];
58
+
59
+ for (size_t i=0; i < sizeof(u); i++)
60
+ sprintf (u2 + (i * 2), "%02x", u1[i]);
61
+
62
+ seed = string (u2);
63
+ #endif
64
+
65
+
66
+ #ifdef OS_WIN32
67
+ UUID uuid;
68
+ UuidCreate (&uuid);
69
+ unsigned char *uuidstring = NULL;
70
+ UuidToString (&uuid, &uuidstring);
71
+ if (!uuidstring)
72
+ throw std::runtime_error ("Unable to read uuid");
73
+ seed = string ((const char*)uuidstring);
74
+
75
+ RpcStringFree (&uuidstring);
76
+ #endif
77
+
78
+ index = 0;
79
+
80
+
81
+ }
82
+
83
+ stringstream ss;
84
+ ss << seed << (++index);
85
+ return ss.str();
86
+ }
87
+ #endif
88
+
89
+ /*****************************
90
+ STATIC: Bindable_t::GetObject
91
+ *****************************/
92
+
93
+ Bindable_t *Bindable_t::GetObject (const unsigned long binding)
94
+ {
95
+ map<unsigned long, Bindable_t*>::const_iterator i = BindingBag.find (binding);
96
+ if (i != BindingBag.end())
97
+ return i->second;
98
+ else
99
+ return NULL;
100
+ }
101
+
102
+
103
+ /**********************
104
+ Bindable_t::Bindable_t
105
+ **********************/
106
+
107
+ Bindable_t::Bindable_t()
108
+ {
109
+ Binding = Bindable_t::CreateBinding();
110
+ BindingBag [Binding] = this;
111
+ }
112
+
113
+
114
+
115
+ /***********************
116
+ Bindable_t::~Bindable_t
117
+ ***********************/
118
+
119
+ Bindable_t::~Bindable_t()
120
+ {
121
+ BindingBag.erase (Binding);
122
+ }
123
+
124
+
@@ -0,0 +1,46 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: binder.h
6
+ Date: 07Apr06
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
+ #ifndef __ObjectBindings__H_
21
+ #define __ObjectBindings__H_
22
+
23
+
24
+ class Bindable_t
25
+ {
26
+ public:
27
+ static unsigned long CreateBinding();
28
+ static Bindable_t *GetObject (const unsigned long);
29
+ static map<unsigned long, Bindable_t*> BindingBag;
30
+
31
+ public:
32
+ Bindable_t();
33
+ virtual ~Bindable_t();
34
+
35
+ const unsigned long GetBinding() {return Binding;}
36
+
37
+ private:
38
+ unsigned long Binding;
39
+ };
40
+
41
+
42
+
43
+
44
+
45
+ #endif // __ObjectBindings__H_
46
+
@@ -0,0 +1,838 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: cmain.cpp
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
+ #include "project.h"
21
+
22
+ /* 21Sep09: ruby 1.9 defines macros for common i/o functions that point to rb_w32_* implementations.
23
+ We need to undef the stat to fix a build failure in evma_send_file_data_to_connection.
24
+ See http://groups.google.com/group/eventmachine/browse_thread/thread/fc60d9bb738ffc71
25
+ */
26
+ #if defined(BUILD_FOR_RUBY) && defined(OS_WIN32)
27
+ #undef stat
28
+ #undef fstat
29
+ #endif
30
+
31
+ static EventMachine_t *EventMachine;
32
+ static int bUseEpoll = 0;
33
+ static int bUseKqueue = 0;
34
+
35
+ extern "C" void ensure_eventmachine (const char *caller = "unknown caller")
36
+ {
37
+ if (!EventMachine) {
38
+ const int err_size = 128;
39
+ char err_string[err_size];
40
+ snprintf (err_string, err_size, "eventmachine not initialized: %s", caller);
41
+ #ifdef BUILD_FOR_RUBY
42
+ rb_raise(rb_eRuntimeError, "%s", err_string);
43
+ #else
44
+ throw std::runtime_error (err_string);
45
+ #endif
46
+ }
47
+ }
48
+
49
+ /***********************
50
+ evma_initialize_library
51
+ ***********************/
52
+
53
+ extern "C" void evma_initialize_library (EMCallback cb)
54
+ {
55
+ if (EventMachine)
56
+ #ifdef BUILD_FOR_RUBY
57
+ rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_initialize_library");
58
+ #else
59
+ throw std::runtime_error ("eventmachine already initialized: evma_initialize_library");
60
+ #endif
61
+ EventMachine = new EventMachine_t (cb);
62
+ if (bUseEpoll)
63
+ EventMachine->_UseEpoll();
64
+ if (bUseKqueue)
65
+ EventMachine->_UseKqueue();
66
+ }
67
+
68
+
69
+ /********************
70
+ evma_release_library
71
+ ********************/
72
+
73
+ extern "C" void evma_release_library()
74
+ {
75
+ ensure_eventmachine("evma_release_library");
76
+ delete EventMachine;
77
+ EventMachine = NULL;
78
+ }
79
+
80
+
81
+ /****************
82
+ evma_run_machine
83
+ ****************/
84
+
85
+ extern "C" void evma_run_machine()
86
+ {
87
+ ensure_eventmachine("evma_run_machine");
88
+ EventMachine->Run();
89
+ }
90
+
91
+
92
+ /**************************
93
+ evma_install_oneshot_timer
94
+ **************************/
95
+
96
+ extern "C" const unsigned long evma_install_oneshot_timer (int seconds)
97
+ {
98
+ ensure_eventmachine("evma_install_oneshot_timer");
99
+ return EventMachine->InstallOneshotTimer (seconds);
100
+ }
101
+
102
+
103
+ /**********************
104
+ evma_connect_to_server
105
+ **********************/
106
+
107
+ extern "C" const unsigned long evma_connect_to_server (const char *bind_addr, int bind_port, const char *server, int port)
108
+ {
109
+ ensure_eventmachine("evma_connect_to_server");
110
+ return EventMachine->ConnectToServer (bind_addr, bind_port, server, port);
111
+ }
112
+
113
+ /***************************
114
+ evma_connect_to_unix_server
115
+ ***************************/
116
+
117
+ extern "C" const unsigned long evma_connect_to_unix_server (const char *server)
118
+ {
119
+ ensure_eventmachine("evma_connect_to_unix_server");
120
+ return EventMachine->ConnectToUnixServer (server);
121
+ }
122
+
123
+ /**************
124
+ evma_attach_fd
125
+ **************/
126
+
127
+ extern "C" const unsigned long evma_attach_fd (int file_descriptor, int watch_mode)
128
+ {
129
+ ensure_eventmachine("evma_attach_fd");
130
+ return EventMachine->AttachFD (file_descriptor, watch_mode ? true : false);
131
+ }
132
+
133
+ /**************
134
+ evma_detach_fd
135
+ **************/
136
+
137
+ extern "C" int evma_detach_fd (const unsigned long binding)
138
+ {
139
+ ensure_eventmachine("evma_detach_fd");
140
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
141
+ if (ed)
142
+ return EventMachine->DetachFD (ed);
143
+ else
144
+ #ifdef BUILD_FOR_RUBY
145
+ rb_raise(rb_eRuntimeError, "invalid binding to detach");
146
+ #else
147
+ throw std::runtime_error ("invalid binding to detach");
148
+ #endif
149
+ return -1;
150
+ }
151
+
152
+ /************************
153
+ evma_get_file_descriptor
154
+ ************************/
155
+
156
+ extern "C" int evma_get_file_descriptor (const unsigned long binding)
157
+ {
158
+ ensure_eventmachine("evma_get_file_descriptor");
159
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
160
+ if (ed)
161
+ return ed->GetSocket();
162
+ else
163
+ #ifdef BUILD_FOR_RUBY
164
+ rb_raise(rb_eRuntimeError, "invalid binding to get_fd");
165
+ #else
166
+ throw std::runtime_error ("invalid binding to get_fd");
167
+ #endif
168
+ return -1;
169
+ }
170
+
171
+ /***********************
172
+ evma_is_notify_readable
173
+ ***********************/
174
+
175
+ extern "C" int evma_is_notify_readable (const unsigned long binding)
176
+ {
177
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
178
+ if (cd)
179
+ return cd->IsNotifyReadable() ? 1 : 0;
180
+ return -1;
181
+ }
182
+
183
+ /************************
184
+ evma_set_notify_readable
185
+ ************************/
186
+
187
+ extern "C" void evma_set_notify_readable (const unsigned long binding, int mode)
188
+ {
189
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
190
+ if (cd)
191
+ cd->SetNotifyReadable (mode ? true : false);
192
+ }
193
+
194
+ /***********************
195
+ evma_is_notify_writable
196
+ ***********************/
197
+
198
+ extern "C" int evma_is_notify_writable (const unsigned long binding)
199
+ {
200
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
201
+ if (cd)
202
+ return cd->IsNotifyWritable() ? 1 : 0;
203
+ return -1;
204
+ }
205
+
206
+ /************************
207
+ evma_set_notify_writable
208
+ ************************/
209
+
210
+ extern "C" void evma_set_notify_writable (const unsigned long binding, int mode)
211
+ {
212
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
213
+ if (cd)
214
+ cd->SetNotifyWritable (mode ? true : false);
215
+ }
216
+
217
+ /**********
218
+ evma_pause
219
+ **********/
220
+
221
+ extern "C" int evma_pause (const unsigned long binding)
222
+ {
223
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
224
+ if (cd)
225
+ return cd->Pause() ? 1 : 0;
226
+
227
+ return 0;
228
+ }
229
+
230
+ /***********
231
+ evma_resume
232
+ ***********/
233
+
234
+ extern "C" int evma_resume (const unsigned long binding)
235
+ {
236
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
237
+ if (cd)
238
+ return cd->Resume() ? 1 : 0;
239
+
240
+ return 0;
241
+ }
242
+
243
+ /**************
244
+ evma_is_paused
245
+ **************/
246
+
247
+ extern "C" int evma_is_paused (const unsigned long binding)
248
+ {
249
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
250
+ if (cd)
251
+ return cd->IsPaused() ? 1 : 0;
252
+
253
+ return 0;
254
+ }
255
+
256
+ /**********************
257
+ evma_create_tcp_server
258
+ **********************/
259
+
260
+ extern "C" const unsigned long evma_create_tcp_server (const char *address, int port)
261
+ {
262
+ ensure_eventmachine("evma_create_tcp_server");
263
+ return EventMachine->CreateTcpServer (address, port);
264
+ }
265
+
266
+ /******************************
267
+ evma_create_unix_domain_server
268
+ ******************************/
269
+
270
+ extern "C" const unsigned long evma_create_unix_domain_server (const char *filename)
271
+ {
272
+ ensure_eventmachine("evma_create_unix_domain_server");
273
+ return EventMachine->CreateUnixDomainServer (filename);
274
+ }
275
+
276
+ /*************************
277
+ evma_open_datagram_socket
278
+ *************************/
279
+
280
+ extern "C" const unsigned long evma_open_datagram_socket (const char *address, int port)
281
+ {
282
+ ensure_eventmachine("evma_open_datagram_socket");
283
+ return EventMachine->OpenDatagramSocket (address, port);
284
+ }
285
+
286
+ /******************
287
+ evma_open_keyboard
288
+ ******************/
289
+
290
+ extern "C" const unsigned long evma_open_keyboard()
291
+ {
292
+ ensure_eventmachine("evma_open_keyboard");
293
+ return EventMachine->OpenKeyboard();
294
+ }
295
+
296
+ /*******************
297
+ evma_watch_filename
298
+ *******************/
299
+
300
+ extern "C" const unsigned long evma_watch_filename (const char *fname)
301
+ {
302
+ ensure_eventmachine("evma_watch_filename");
303
+ return EventMachine->WatchFile(fname);
304
+ }
305
+
306
+ /*********************
307
+ evma_unwatch_filename
308
+ *********************/
309
+
310
+ extern "C" void evma_unwatch_filename (const unsigned long sig)
311
+ {
312
+ ensure_eventmachine("evma_unwatch_file");
313
+ EventMachine->UnwatchFile(sig);
314
+ }
315
+
316
+ /**************
317
+ evma_watch_pid
318
+ **************/
319
+
320
+ extern "C" const unsigned long evma_watch_pid (int pid)
321
+ {
322
+ ensure_eventmachine("evma_watch_pid");
323
+ return EventMachine->WatchPid(pid);
324
+ }
325
+
326
+ /****************
327
+ evma_unwatch_pid
328
+ ****************/
329
+
330
+ extern "C" void evma_unwatch_pid (const unsigned long sig)
331
+ {
332
+ ensure_eventmachine("evma_unwatch_pid");
333
+ EventMachine->UnwatchPid(sig);
334
+ }
335
+
336
+ /****************************
337
+ evma_send_data_to_connection
338
+ ****************************/
339
+
340
+ extern "C" int evma_send_data_to_connection (const unsigned long binding, const char *data, int data_length)
341
+ {
342
+ ensure_eventmachine("evma_send_data_to_connection");
343
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
344
+ if (ed)
345
+ return ed->SendOutboundData(data, data_length);
346
+ return -1;
347
+ }
348
+
349
+ /******************
350
+ evma_send_datagram
351
+ ******************/
352
+
353
+ extern "C" int evma_send_datagram (const unsigned long binding, const char *data, int data_length, const char *address, int port)
354
+ {
355
+ ensure_eventmachine("evma_send_datagram");
356
+ DatagramDescriptor *dd = dynamic_cast <DatagramDescriptor*> (Bindable_t::GetObject (binding));
357
+ if (dd)
358
+ return dd->SendOutboundDatagram(data, data_length, address, port);
359
+ return -1;
360
+ }
361
+
362
+
363
+ /*********************
364
+ evma_close_connection
365
+ *********************/
366
+
367
+ extern "C" void evma_close_connection (const unsigned long binding, int after_writing)
368
+ {
369
+ ensure_eventmachine("evma_close_connection");
370
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
371
+ if (ed)
372
+ ed->ScheduleClose (after_writing ? true : false);
373
+ }
374
+
375
+ /***********************************
376
+ evma_report_connection_error_status
377
+ ***********************************/
378
+
379
+ extern "C" int evma_report_connection_error_status (const unsigned long binding)
380
+ {
381
+ ensure_eventmachine("evma_report_connection_error_status");
382
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
383
+ if (ed)
384
+ return ed->ReportErrorStatus();
385
+ return -1;
386
+ }
387
+
388
+ /********************
389
+ evma_stop_tcp_server
390
+ ********************/
391
+
392
+ extern "C" void evma_stop_tcp_server (const unsigned long binding)
393
+ {
394
+ ensure_eventmachine("evma_stop_tcp_server");
395
+ AcceptorDescriptor::StopAcceptor (binding);
396
+ }
397
+
398
+
399
+ /*****************
400
+ evma_stop_machine
401
+ *****************/
402
+
403
+ extern "C" void evma_stop_machine()
404
+ {
405
+ ensure_eventmachine("evma_stop_machine");
406
+ EventMachine->ScheduleHalt();
407
+ }
408
+
409
+
410
+ /**************
411
+ evma_start_tls
412
+ **************/
413
+
414
+ extern "C" void evma_start_tls (const unsigned long binding)
415
+ {
416
+ ensure_eventmachine("evma_start_tls");
417
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
418
+ if (ed)
419
+ ed->StartTls();
420
+ }
421
+
422
+ /******************
423
+ evma_set_tls_parms
424
+ ******************/
425
+
426
+ extern "C" void evma_set_tls_parms (const unsigned long binding, const char *privatekey_filename, const char *certchain_filename, int verify_peer)
427
+ {
428
+ ensure_eventmachine("evma_set_tls_parms");
429
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
430
+ if (ed)
431
+ ed->SetTlsParms (privatekey_filename, certchain_filename, (verify_peer == 1 ? true : false));
432
+ }
433
+
434
+ /******************
435
+ evma_get_peer_cert
436
+ ******************/
437
+
438
+ #ifdef WITH_SSL
439
+ extern "C" X509 *evma_get_peer_cert (const unsigned long binding)
440
+ {
441
+ ensure_eventmachine("evma_get_peer_cert");
442
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
443
+ if (ed)
444
+ return ed->GetPeerCert();
445
+ return NULL;
446
+ }
447
+ #endif
448
+
449
+ /********************
450
+ evma_accept_ssl_peer
451
+ ********************/
452
+
453
+ #ifdef WITH_SSL
454
+ extern "C" void evma_accept_ssl_peer (const unsigned long binding)
455
+ {
456
+ ensure_eventmachine("evma_accept_ssl_peer");
457
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
458
+ if (cd)
459
+ cd->AcceptSslPeer();
460
+ }
461
+ #endif
462
+
463
+ /*****************
464
+ evma_get_peername
465
+ *****************/
466
+
467
+ extern "C" int evma_get_peername (const unsigned long binding, struct sockaddr *sa)
468
+ {
469
+ ensure_eventmachine("evma_get_peername");
470
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
471
+ if (ed) {
472
+ return ed->GetPeername (sa) ? 1 : 0;
473
+ }
474
+ else
475
+ return 0;
476
+ }
477
+
478
+ /*****************
479
+ evma_get_sockname
480
+ *****************/
481
+
482
+ extern "C" int evma_get_sockname (const unsigned long binding, struct sockaddr *sa)
483
+ {
484
+ ensure_eventmachine("evma_get_sockname");
485
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
486
+ if (ed) {
487
+ return ed->GetSockname (sa) ? 1 : 0;
488
+ }
489
+ else
490
+ return 0;
491
+ }
492
+
493
+ /***********************
494
+ evma_get_subprocess_pid
495
+ ***********************/
496
+
497
+ extern "C" int evma_get_subprocess_pid (const unsigned long binding, pid_t *pid)
498
+ {
499
+ ensure_eventmachine("evma_get_subprocess_pid");
500
+ #ifdef OS_UNIX
501
+ PipeDescriptor *pd = dynamic_cast <PipeDescriptor*> (Bindable_t::GetObject (binding));
502
+ if (pd) {
503
+ return pd->GetSubprocessPid (pid) ? 1 : 0;
504
+ }
505
+ else if (pid && EventMachine->SubprocessPid) {
506
+ *pid = EventMachine->SubprocessPid;
507
+ return 1;
508
+ }
509
+ else
510
+ return 0;
511
+ #else
512
+ return 0;
513
+ #endif
514
+ }
515
+
516
+ /**************************
517
+ evma_get_subprocess_status
518
+ **************************/
519
+
520
+ extern "C" int evma_get_subprocess_status (const unsigned long binding, int *status)
521
+ {
522
+ ensure_eventmachine("evma_get_subprocess_status");
523
+ if (status) {
524
+ *status = EventMachine->SubprocessExitStatus;
525
+ return 1;
526
+ }
527
+ else
528
+ return 0;
529
+ }
530
+
531
+ /*************************
532
+ evma_get_connection_count
533
+ *************************/
534
+
535
+ extern "C" int evma_get_connection_count()
536
+ {
537
+ ensure_eventmachine("evma_get_connection_count");
538
+ return EventMachine->GetConnectionCount();
539
+ }
540
+
541
+ /*********************
542
+ evma_signal_loopbreak
543
+ *********************/
544
+
545
+ extern "C" void evma_signal_loopbreak()
546
+ {
547
+ ensure_eventmachine("evma_signal_loopbreak");
548
+ EventMachine->SignalLoopBreaker();
549
+ }
550
+
551
+
552
+
553
+ /********************************
554
+ evma_get_comm_inactivity_timeout
555
+ ********************************/
556
+
557
+ extern "C" float evma_get_comm_inactivity_timeout (const unsigned long binding)
558
+ {
559
+ ensure_eventmachine("evma_get_comm_inactivity_timeout");
560
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
561
+ if (ed) {
562
+ return ((float)ed->GetCommInactivityTimeout() / 1000);
563
+ }
564
+ else
565
+ return 0.0; //Perhaps this should be an exception. Access to an unknown binding.
566
+ }
567
+
568
+ /********************************
569
+ evma_set_comm_inactivity_timeout
570
+ ********************************/
571
+
572
+ extern "C" int evma_set_comm_inactivity_timeout (const unsigned long binding, float value)
573
+ {
574
+ ensure_eventmachine("evma_set_comm_inactivity_timeout");
575
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
576
+ if (ed) {
577
+ return ed->SetCommInactivityTimeout ((uint64_t)(value * 1000));
578
+ }
579
+ else
580
+ return 0; //Perhaps this should be an exception. Access to an unknown binding.
581
+ }
582
+
583
+
584
+ /********************************
585
+ evma_get_pending_connect_timeout
586
+ ********************************/
587
+
588
+ extern "C" float evma_get_pending_connect_timeout (const unsigned long binding)
589
+ {
590
+ ensure_eventmachine("evma_get_pending_connect_timeout");
591
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
592
+ if (ed) {
593
+ return ((float)ed->GetPendingConnectTimeout() / 1000);
594
+ }
595
+ else
596
+ return 0.0;
597
+ }
598
+
599
+
600
+ /********************************
601
+ evma_set_pending_connect_timeout
602
+ ********************************/
603
+
604
+ extern "C" int evma_set_pending_connect_timeout (const unsigned long binding, float value)
605
+ {
606
+ ensure_eventmachine("evma_set_pending_connect_timeout");
607
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
608
+ if (ed) {
609
+ return ed->SetPendingConnectTimeout ((uint64_t)(value * 1000));
610
+ }
611
+ else
612
+ return 0;
613
+ }
614
+
615
+
616
+ /**********************
617
+ evma_set_timer_quantum
618
+ **********************/
619
+
620
+ extern "C" void evma_set_timer_quantum (int interval)
621
+ {
622
+ ensure_eventmachine("evma_set_timer_quantum");
623
+ EventMachine->SetTimerQuantum (interval);
624
+ }
625
+
626
+
627
+ /************************
628
+ evma_get_max_timer_count
629
+ ************************/
630
+
631
+ extern "C" int evma_get_max_timer_count()
632
+ {
633
+ return EventMachine_t::GetMaxTimerCount();
634
+ }
635
+
636
+
637
+ /************************
638
+ evma_set_max_timer_count
639
+ ************************/
640
+
641
+ extern "C" void evma_set_max_timer_count (int ct)
642
+ {
643
+ // This may only be called if the reactor is not running.
644
+
645
+ if (EventMachine)
646
+ #ifdef BUILD_FOR_RUBY
647
+ rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_set_max_timer_count");
648
+ #else
649
+ throw std::runtime_error ("eventmachine already initialized: evma_set_max_timer_count");
650
+ #endif
651
+ EventMachine_t::SetMaxTimerCount (ct);
652
+ }
653
+
654
+ /******************
655
+ evma_setuid_string
656
+ ******************/
657
+
658
+ extern "C" void evma_setuid_string (const char *username)
659
+ {
660
+ // We do NOT need to be running an EM instance because this method is static.
661
+ EventMachine_t::SetuidString (username);
662
+ }
663
+
664
+
665
+ /**********
666
+ evma_popen
667
+ **********/
668
+
669
+ extern "C" const unsigned long evma_popen (char * const*cmd_strings)
670
+ {
671
+ ensure_eventmachine("evma_popen");
672
+ return EventMachine->Socketpair (cmd_strings);
673
+ }
674
+
675
+
676
+ /***************************
677
+ evma_get_outbound_data_size
678
+ ***************************/
679
+
680
+ extern "C" int evma_get_outbound_data_size (const unsigned long binding)
681
+ {
682
+ ensure_eventmachine("evma_get_outbound_data_size");
683
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
684
+ return ed ? ed->GetOutboundDataSize() : 0;
685
+ }
686
+
687
+
688
+ /**************
689
+ evma_set_epoll
690
+ **************/
691
+
692
+ extern "C" void evma_set_epoll (int use)
693
+ {
694
+ bUseEpoll = !!use;
695
+ }
696
+
697
+ /***************
698
+ evma_set_kqueue
699
+ ***************/
700
+
701
+ extern "C" void evma_set_kqueue (int use)
702
+ {
703
+ bUseKqueue = !!use;
704
+ }
705
+
706
+
707
+ /**********************
708
+ evma_set_rlimit_nofile
709
+ **********************/
710
+
711
+ extern "C" int evma_set_rlimit_nofile (int nofiles)
712
+ {
713
+ return EventMachine_t::SetRlimitNofile (nofiles);
714
+ }
715
+
716
+
717
+ /*********************************
718
+ evma_send_file_data_to_connection
719
+ *********************************/
720
+
721
+ extern "C" int evma_send_file_data_to_connection (const unsigned long binding, const char *filename)
722
+ {
723
+ /* This is a sugaring over send_data_to_connection that reads a file into a
724
+ * locally-allocated buffer, and sends the file data to the remote peer.
725
+ * Return the number of bytes written to the caller.
726
+ * TODO, needs to impose a limit on the file size. This is intended only for
727
+ * small files. (I don't know, maybe 8K or less.) For larger files, use interleaved
728
+ * I/O to avoid slowing the rest of the system down.
729
+ * TODO: we should return a code rather than barf, in case of file-not-found.
730
+ * TODO, does this compile on Windows?
731
+ * TODO, given that we want this to work only with small files, how about allocating
732
+ * the buffer on the stack rather than the heap?
733
+ *
734
+ * Modified 25Jul07. This now returns -1 on file-too-large; 0 for success, and a positive
735
+ * errno in case of other errors.
736
+ *
737
+ * Contributed by Kirk Haines.
738
+ */
739
+
740
+ char data[32*1024];
741
+ int r;
742
+
743
+ ensure_eventmachine("evma_send_file_data_to_connection");
744
+
745
+ int Fd = open (filename, O_RDONLY);
746
+
747
+ if (Fd < 0)
748
+ return errno;
749
+ // From here on, all early returns MUST close Fd.
750
+
751
+ struct stat st;
752
+ if (fstat (Fd, &st)) {
753
+ int e = errno;
754
+ close (Fd);
755
+ return e;
756
+ }
757
+
758
+ off_t filesize = st.st_size;
759
+ if (filesize <= 0) {
760
+ close (Fd);
761
+ return 0;
762
+ }
763
+ else if (filesize > (off_t) sizeof(data)) {
764
+ close (Fd);
765
+ return -1;
766
+ }
767
+
768
+
769
+ r = read (Fd, data, filesize);
770
+ if (r != filesize) {
771
+ int e = errno;
772
+ close (Fd);
773
+ return e;
774
+ }
775
+ evma_send_data_to_connection (binding, data, r);
776
+ close (Fd);
777
+
778
+ return 0;
779
+ }
780
+
781
+
782
+ /****************
783
+ evma_start_proxy
784
+ *****************/
785
+
786
+ extern "C" void evma_start_proxy (const unsigned long from, const unsigned long to, const unsigned long bufsize, const unsigned long length)
787
+ {
788
+ ensure_eventmachine("evma_start_proxy");
789
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
790
+ if (ed)
791
+ ed->StartProxy(to, bufsize, length);
792
+ }
793
+
794
+
795
+ /***************
796
+ evma_stop_proxy
797
+ ****************/
798
+
799
+ extern "C" void evma_stop_proxy (const unsigned long from)
800
+ {
801
+ ensure_eventmachine("evma_stop_proxy");
802
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
803
+ if (ed)
804
+ ed->StopProxy();
805
+ }
806
+
807
+
808
+ /***************************
809
+ evma_get_heartbeat_interval
810
+ ****************************/
811
+
812
+ extern "C" float evma_get_heartbeat_interval()
813
+ {
814
+ ensure_eventmachine("evma_get_heartbeat_interval");
815
+ return EventMachine->GetHeartbeatInterval();
816
+ }
817
+
818
+
819
+ /***************************
820
+ evma_set_heartbeat_interval
821
+ ****************************/
822
+
823
+ extern "C" int evma_set_heartbeat_interval(float interval)
824
+ {
825
+ ensure_eventmachine("evma_set_heartbeat_interval");
826
+ return EventMachine->SetHeartbeatInterval(interval);
827
+ }
828
+
829
+
830
+ /**************************
831
+ evma_get_current_loop_time
832
+ ***************************/
833
+
834
+ extern "C" uint64_t evma_get_current_loop_time()
835
+ {
836
+ ensure_eventmachine("evma_get_current_loop_time");
837
+ return EventMachine->GetCurrentLoopTime();
838
+ }