sensu-em 2.4.0-x86-mingw32
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.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.travis.yml +12 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +33 -0
- data/GNU +281 -0
- data/Gemfile +2 -0
- data/LICENSE +60 -0
- data/README.md +109 -0
- data/Rakefile +20 -0
- data/docs/DocumentationGuidesIndex.md +27 -0
- data/docs/GettingStarted.md +521 -0
- data/docs/old/ChangeLog +211 -0
- data/docs/old/DEFERRABLES +246 -0
- data/docs/old/EPOLL +141 -0
- data/docs/old/INSTALL +13 -0
- data/docs/old/KEYBOARD +42 -0
- data/docs/old/LEGAL +25 -0
- data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
- data/docs/old/PURE_RUBY +75 -0
- data/docs/old/RELEASE_NOTES +94 -0
- data/docs/old/SMTP +4 -0
- data/docs/old/SPAWNED_PROCESSES +148 -0
- data/docs/old/TODO +8 -0
- data/eventmachine.gemspec +37 -0
- data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
- data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
- data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
- data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
- data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
- data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
- data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
- data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
- data/examples/old/ex_channel.rb +43 -0
- data/examples/old/ex_queue.rb +2 -0
- data/examples/old/ex_tick_loop_array.rb +15 -0
- data/examples/old/ex_tick_loop_counter.rb +32 -0
- data/examples/old/helper.rb +2 -0
- data/ext/binder.cpp +124 -0
- data/ext/binder.h +46 -0
- data/ext/cmain.cpp +887 -0
- data/ext/ed.cpp +1992 -0
- data/ext/ed.h +424 -0
- data/ext/em.cpp +2352 -0
- data/ext/em.h +253 -0
- data/ext/eventmachine.h +128 -0
- data/ext/extconf.rb +179 -0
- data/ext/fastfilereader/extconf.rb +103 -0
- data/ext/fastfilereader/mapper.cpp +214 -0
- data/ext/fastfilereader/mapper.h +59 -0
- data/ext/fastfilereader/rubymain.cpp +127 -0
- data/ext/kb.cpp +79 -0
- data/ext/page.cpp +107 -0
- data/ext/page.h +51 -0
- data/ext/pipe.cpp +347 -0
- data/ext/project.h +161 -0
- data/ext/rubymain.cpp +1318 -0
- data/ext/ssl.cpp +476 -0
- data/ext/ssl.h +95 -0
- data/java/.classpath +6 -0
- data/java/.gitignore +1 -0
- data/java/.project +17 -0
- data/java/src/com/rubyeventmachine/DatagramPacket.java +13 -0
- data/java/src/com/rubyeventmachine/EmReactor.java +531 -0
- data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
- data/java/src/com/rubyeventmachine/EventCallback.java +7 -0
- data/java/src/com/rubyeventmachine/EventCode.java +26 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +130 -0
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +179 -0
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +405 -0
- data/java/src/com/rubyeventmachine/SslBox.java +311 -0
- data/lib/em/buftok.rb +110 -0
- data/lib/em/callback.rb +58 -0
- data/lib/em/channel.rb +64 -0
- data/lib/em/completion.rb +304 -0
- data/lib/em/connection.rb +716 -0
- data/lib/em/deferrable.rb +210 -0
- data/lib/em/deferrable/pool.rb +2 -0
- data/lib/em/file_watch.rb +73 -0
- data/lib/em/future.rb +61 -0
- data/lib/em/iterator.rb +231 -0
- data/lib/em/messages.rb +66 -0
- data/lib/em/pool.rb +151 -0
- data/lib/em/process_watch.rb +45 -0
- data/lib/em/processes.rb +123 -0
- data/lib/em/protocols.rb +37 -0
- data/lib/em/protocols/header_and_content.rb +138 -0
- data/lib/em/protocols/httpclient.rb +279 -0
- data/lib/em/protocols/httpclient2.rb +600 -0
- data/lib/em/protocols/line_and_text.rb +125 -0
- data/lib/em/protocols/line_protocol.rb +29 -0
- data/lib/em/protocols/linetext2.rb +161 -0
- data/lib/em/protocols/memcache.rb +331 -0
- data/lib/em/protocols/object_protocol.rb +46 -0
- data/lib/em/protocols/postgres3.rb +246 -0
- data/lib/em/protocols/saslauth.rb +175 -0
- data/lib/em/protocols/smtpclient.rb +365 -0
- data/lib/em/protocols/smtpserver.rb +643 -0
- data/lib/em/protocols/socks4.rb +66 -0
- data/lib/em/protocols/stomp.rb +205 -0
- data/lib/em/protocols/tcptest.rb +54 -0
- data/lib/em/pure_ruby.rb +1017 -0
- data/lib/em/queue.rb +71 -0
- data/lib/em/resolver.rb +209 -0
- data/lib/em/spawnable.rb +84 -0
- data/lib/em/streamer.rb +118 -0
- data/lib/em/threaded_resource.rb +90 -0
- data/lib/em/tick_loop.rb +85 -0
- data/lib/em/timers.rb +61 -0
- data/lib/em/version.rb +3 -0
- data/lib/eventmachine.rb +1553 -0
- data/lib/fastfilereaderext.rb +2 -0
- data/lib/jeventmachine.rb +321 -0
- data/lib/rubyeventmachine.rb +2 -0
- data/rakelib/cpp.rake_example +77 -0
- data/rakelib/package.rake +98 -0
- data/rakelib/test.rake +8 -0
- data/tests/client.crt +31 -0
- data/tests/client.key +51 -0
- data/tests/em_test_helper.rb +64 -0
- data/tests/server.crt +36 -0
- data/tests/server.key +51 -0
- data/tests/test_attach.rb +150 -0
- data/tests/test_basic.rb +294 -0
- data/tests/test_channel.rb +62 -0
- data/tests/test_completion.rb +177 -0
- data/tests/test_connection_count.rb +53 -0
- data/tests/test_defer.rb +18 -0
- data/tests/test_deferrable.rb +35 -0
- data/tests/test_epoll.rb +145 -0
- data/tests/test_error_handler.rb +38 -0
- data/tests/test_exc.rb +28 -0
- data/tests/test_file_watch.rb +65 -0
- data/tests/test_futures.rb +170 -0
- data/tests/test_get_sock_opt.rb +37 -0
- data/tests/test_handler_check.rb +35 -0
- data/tests/test_hc.rb +155 -0
- data/tests/test_httpclient.rb +190 -0
- data/tests/test_httpclient2.rb +133 -0
- data/tests/test_idle_connection.rb +25 -0
- data/tests/test_inactivity_timeout.rb +54 -0
- data/tests/test_iterator.rb +97 -0
- data/tests/test_kb.rb +34 -0
- data/tests/test_line_protocol.rb +33 -0
- data/tests/test_ltp.rb +138 -0
- data/tests/test_ltp2.rb +288 -0
- data/tests/test_next_tick.rb +104 -0
- data/tests/test_object_protocol.rb +36 -0
- data/tests/test_pause.rb +102 -0
- data/tests/test_pending_connect_timeout.rb +52 -0
- data/tests/test_pool.rb +194 -0
- data/tests/test_process_watch.rb +48 -0
- data/tests/test_processes.rb +128 -0
- data/tests/test_proxy_connection.rb +180 -0
- data/tests/test_pure.rb +88 -0
- data/tests/test_queue.rb +50 -0
- data/tests/test_resolver.rb +55 -0
- data/tests/test_running.rb +14 -0
- data/tests/test_sasl.rb +47 -0
- data/tests/test_send_file.rb +217 -0
- data/tests/test_servers.rb +33 -0
- data/tests/test_set_sock_opt.rb +37 -0
- data/tests/test_shutdown_hooks.rb +23 -0
- data/tests/test_smtpclient.rb +55 -0
- data/tests/test_smtpserver.rb +57 -0
- data/tests/test_spawn.rb +293 -0
- data/tests/test_ssl_args.rb +78 -0
- data/tests/test_ssl_echo_data.rb +60 -0
- data/tests/test_ssl_methods.rb +56 -0
- data/tests/test_ssl_verify.rb +82 -0
- data/tests/test_stomp.rb +37 -0
- data/tests/test_system.rb +42 -0
- data/tests/test_threaded_resource.rb +53 -0
- data/tests/test_tick_loop.rb +59 -0
- data/tests/test_timers.rb +123 -0
- data/tests/test_ud.rb +8 -0
- data/tests/test_unbind_reason.rb +48 -0
- metadata +300 -0
data/ext/ssl.h
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
/*****************************************************************************
|
2
|
+
|
3
|
+
$Id$
|
4
|
+
|
5
|
+
File: ssl.h
|
6
|
+
Date: 30Apr06
|
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
|
+
#ifndef __SslBox__H_
|
22
|
+
#define __SslBox__H_
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
#ifdef WITH_SSL
|
28
|
+
|
29
|
+
/******************
|
30
|
+
class SslContext_t
|
31
|
+
******************/
|
32
|
+
|
33
|
+
class SslContext_t
|
34
|
+
{
|
35
|
+
public:
|
36
|
+
SslContext_t (bool is_server, const string &privkeyfile, const string &certchainfile, bool use_tls, const string &cipherlist);
|
37
|
+
virtual ~SslContext_t();
|
38
|
+
|
39
|
+
private:
|
40
|
+
static bool bLibraryInitialized;
|
41
|
+
|
42
|
+
private:
|
43
|
+
bool bIsServer;
|
44
|
+
SSL_CTX *pCtx;
|
45
|
+
|
46
|
+
EVP_PKEY *PrivateKey;
|
47
|
+
X509 *Certificate;
|
48
|
+
|
49
|
+
friend class SslBox_t;
|
50
|
+
};
|
51
|
+
|
52
|
+
|
53
|
+
/**************
|
54
|
+
class SslBox_t
|
55
|
+
**************/
|
56
|
+
|
57
|
+
class SslBox_t
|
58
|
+
{
|
59
|
+
public:
|
60
|
+
SslBox_t (bool is_server, const string &privkeyfile, const string &certchainfile, bool verify_peer, bool use_tls, const string &cipherlist, const unsigned long binding);
|
61
|
+
virtual ~SslBox_t();
|
62
|
+
|
63
|
+
int PutPlaintext (const char*, int);
|
64
|
+
int GetPlaintext (char*, int);
|
65
|
+
|
66
|
+
bool PutCiphertext (const char*, int);
|
67
|
+
bool CanGetCiphertext();
|
68
|
+
int GetCiphertext (char*, int);
|
69
|
+
bool IsHandshakeCompleted() {return bHandshakeCompleted;}
|
70
|
+
|
71
|
+
X509 *GetPeerCert();
|
72
|
+
|
73
|
+
void Shutdown();
|
74
|
+
|
75
|
+
protected:
|
76
|
+
SslContext_t *Context;
|
77
|
+
|
78
|
+
bool bIsServer;
|
79
|
+
bool bHandshakeCompleted;
|
80
|
+
bool bVerifyPeer;
|
81
|
+
bool bUseTls;
|
82
|
+
SSL *pSSL;
|
83
|
+
BIO *pbioRead;
|
84
|
+
BIO *pbioWrite;
|
85
|
+
|
86
|
+
PageList OutboundQ;
|
87
|
+
};
|
88
|
+
|
89
|
+
extern "C" int ssl_verify_wrapper(int, X509_STORE_CTX*);
|
90
|
+
|
91
|
+
#endif // WITH_SSL
|
92
|
+
|
93
|
+
|
94
|
+
#endif // __SslBox__H_
|
95
|
+
|
data/java/.classpath
ADDED
data/java/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/bin
|
data/java/.project
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<projectDescription>
|
3
|
+
<name>em_reactor</name>
|
4
|
+
<comment></comment>
|
5
|
+
<projects>
|
6
|
+
</projects>
|
7
|
+
<buildSpec>
|
8
|
+
<buildCommand>
|
9
|
+
<name>org.eclipse.jdt.core.javabuilder</name>
|
10
|
+
<arguments>
|
11
|
+
</arguments>
|
12
|
+
</buildCommand>
|
13
|
+
</buildSpec>
|
14
|
+
<natures>
|
15
|
+
<nature>org.eclipse.jdt.core.javanature</nature>
|
16
|
+
</natures>
|
17
|
+
</projectDescription>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
package com.rubyeventmachine;
|
2
|
+
|
3
|
+
import java.net.SocketAddress;
|
4
|
+
import java.nio.ByteBuffer;
|
5
|
+
|
6
|
+
class DatagramPacket {
|
7
|
+
public ByteBuffer bb;
|
8
|
+
public SocketAddress recipient;
|
9
|
+
public DatagramPacket (ByteBuffer _bb, SocketAddress _recipient) {
|
10
|
+
bb = _bb;
|
11
|
+
recipient = _recipient;
|
12
|
+
}
|
13
|
+
}
|
@@ -0,0 +1,531 @@
|
|
1
|
+
/**
|
2
|
+
* $Id$
|
3
|
+
*
|
4
|
+
* Author:: Francis Cianfrocca (gmail: blackhedd)
|
5
|
+
* Homepage:: http://rubyeventmachine.com
|
6
|
+
* Date:: 15 Jul 2007
|
7
|
+
*
|
8
|
+
* See EventMachine and EventMachine::Connection for documentation and
|
9
|
+
* usage examples.
|
10
|
+
*
|
11
|
+
*
|
12
|
+
*----------------------------------------------------------------------------
|
13
|
+
*
|
14
|
+
* Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
|
15
|
+
* Gmail: blackhedd
|
16
|
+
*
|
17
|
+
* This program is free software; you can redistribute it and/or modify
|
18
|
+
* it under the terms of either: 1) the GNU General Public License
|
19
|
+
* as published by the Free Software Foundation; either version 2 of the
|
20
|
+
* License, or (at your option) any later version; or 2) Ruby's License.
|
21
|
+
*
|
22
|
+
* See the file COPYING for complete licensing information.
|
23
|
+
*
|
24
|
+
*---------------------------------------------------------------------------
|
25
|
+
*
|
26
|
+
*
|
27
|
+
*/
|
28
|
+
|
29
|
+
package com.rubyeventmachine;
|
30
|
+
|
31
|
+
import java.io.IOException;
|
32
|
+
import java.net.InetSocketAddress;
|
33
|
+
import java.net.SocketAddress;
|
34
|
+
import java.nio.ByteBuffer;
|
35
|
+
import java.nio.channels.ClosedChannelException;
|
36
|
+
import java.nio.channels.DatagramChannel;
|
37
|
+
import java.nio.channels.SelectionKey;
|
38
|
+
import java.nio.channels.Selector;
|
39
|
+
import java.nio.channels.ServerSocketChannel;
|
40
|
+
import java.nio.channels.SocketChannel;
|
41
|
+
import java.security.KeyManagementException;
|
42
|
+
import java.security.KeyStore;
|
43
|
+
import java.security.NoSuchAlgorithmException;
|
44
|
+
import java.util.ArrayList;
|
45
|
+
import java.util.Date;
|
46
|
+
import java.util.HashMap;
|
47
|
+
import java.util.Iterator;
|
48
|
+
import java.util.TreeMap;
|
49
|
+
import java.util.concurrent.atomic.AtomicBoolean;
|
50
|
+
|
51
|
+
public class EmReactor {
|
52
|
+
private Selector mySelector;
|
53
|
+
private TreeMap<Long, ArrayList<Long>> Timers;
|
54
|
+
private HashMap<Long, EventableChannel<?>> Connections;
|
55
|
+
private HashMap<Long, ServerSocketChannel> Acceptors;
|
56
|
+
private ArrayList<Long> NewConnections;
|
57
|
+
private ArrayList<Long> UnboundConnections;
|
58
|
+
private ArrayList<EventableSocketChannel> DetachedConnections;
|
59
|
+
|
60
|
+
private boolean bRunReactor;
|
61
|
+
private long BindingIndex;
|
62
|
+
private AtomicBoolean loopBreaker;
|
63
|
+
private int timerQuantum;
|
64
|
+
private EventCallback callback;
|
65
|
+
|
66
|
+
public EmReactor(EventCallback callback) {
|
67
|
+
this.callback = callback;
|
68
|
+
Timers = new TreeMap<Long, ArrayList<Long>>();
|
69
|
+
Connections = new HashMap<Long, EventableChannel<?>>();
|
70
|
+
Acceptors = new HashMap<Long, ServerSocketChannel>();
|
71
|
+
NewConnections = new ArrayList<Long>();
|
72
|
+
UnboundConnections = new ArrayList<Long>();
|
73
|
+
DetachedConnections = new ArrayList<EventableSocketChannel>();
|
74
|
+
|
75
|
+
BindingIndex = 0;
|
76
|
+
loopBreaker = new AtomicBoolean();
|
77
|
+
loopBreaker.set(false);
|
78
|
+
timerQuantum = 98;
|
79
|
+
}
|
80
|
+
|
81
|
+
public void run() {
|
82
|
+
try {
|
83
|
+
mySelector = Selector.open();
|
84
|
+
bRunReactor = true;
|
85
|
+
} catch (IOException e) {
|
86
|
+
throw new RuntimeException ("Could not open selector", e);
|
87
|
+
}
|
88
|
+
|
89
|
+
while (bRunReactor) {
|
90
|
+
runLoopbreaks();
|
91
|
+
if (!bRunReactor) break;
|
92
|
+
|
93
|
+
runTimers();
|
94
|
+
if (!bRunReactor) break;
|
95
|
+
|
96
|
+
removeUnboundConnections();
|
97
|
+
checkIO();
|
98
|
+
addNewConnections();
|
99
|
+
processIO();
|
100
|
+
}
|
101
|
+
|
102
|
+
close();
|
103
|
+
}
|
104
|
+
|
105
|
+
void addNewConnections() {
|
106
|
+
for (EventableSocketChannel ec : DetachedConnections) {
|
107
|
+
ec.cleanup();
|
108
|
+
}
|
109
|
+
DetachedConnections.clear();
|
110
|
+
|
111
|
+
for (long b : NewConnections) {
|
112
|
+
EventableChannel<?> ec = Connections.get(b);
|
113
|
+
if (ec != null) {
|
114
|
+
try {
|
115
|
+
ec.register();
|
116
|
+
} catch (ClosedChannelException e) {
|
117
|
+
UnboundConnections.add (ec.getBinding());
|
118
|
+
}
|
119
|
+
}
|
120
|
+
}
|
121
|
+
NewConnections.clear();
|
122
|
+
}
|
123
|
+
|
124
|
+
void removeUnboundConnections() {
|
125
|
+
for (long b : UnboundConnections) {
|
126
|
+
EventableChannel<?> ec = Connections.remove(b);
|
127
|
+
if (ec != null) {
|
128
|
+
callback.trigger(b, EventCode.EM_CONNECTION_UNBOUND, null, (long) 0);
|
129
|
+
ec.close();
|
130
|
+
|
131
|
+
EventableSocketChannel sc = (EventableSocketChannel) ec;
|
132
|
+
if (sc != null && sc.isAttached())
|
133
|
+
DetachedConnections.add (sc);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
UnboundConnections.clear();
|
137
|
+
}
|
138
|
+
|
139
|
+
void checkIO() {
|
140
|
+
long timeout;
|
141
|
+
|
142
|
+
if (NewConnections.size() > 0) {
|
143
|
+
timeout = -1;
|
144
|
+
} else if (!Timers.isEmpty()) {
|
145
|
+
long now = new Date().getTime();
|
146
|
+
long k = Timers.firstKey();
|
147
|
+
long diff = k-now;
|
148
|
+
|
149
|
+
if (diff <= 0)
|
150
|
+
timeout = -1; // don't wait, just poll once
|
151
|
+
else
|
152
|
+
timeout = diff;
|
153
|
+
} else {
|
154
|
+
timeout = 0; // wait indefinitely
|
155
|
+
}
|
156
|
+
|
157
|
+
try {
|
158
|
+
if (timeout == -1)
|
159
|
+
mySelector.selectNow();
|
160
|
+
else
|
161
|
+
mySelector.select(timeout);
|
162
|
+
} catch (IOException e) {
|
163
|
+
e.printStackTrace();
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
void processIO() {
|
168
|
+
Iterator<SelectionKey> it = mySelector.selectedKeys().iterator();
|
169
|
+
while (it.hasNext()) {
|
170
|
+
SelectionKey k = it.next();
|
171
|
+
it.remove();
|
172
|
+
if (k.isConnectable()) {
|
173
|
+
isConnectable(k);
|
174
|
+
}
|
175
|
+
else if (k.isAcceptable()) {
|
176
|
+
isAcceptable(k);
|
177
|
+
}
|
178
|
+
else {
|
179
|
+
if (k.isWritable())
|
180
|
+
isWritable(k);
|
181
|
+
|
182
|
+
if (k.isReadable())
|
183
|
+
isReadable(k);
|
184
|
+
}
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
void isAcceptable (SelectionKey k) {
|
189
|
+
ServerSocketChannel ss = (ServerSocketChannel) k.channel();
|
190
|
+
SocketChannel sn;
|
191
|
+
long b;
|
192
|
+
|
193
|
+
for (int n = 0; n < 10; n++) {
|
194
|
+
try {
|
195
|
+
sn = ss.accept();
|
196
|
+
if (sn == null)
|
197
|
+
break;
|
198
|
+
} catch (IOException e) {
|
199
|
+
e.printStackTrace();
|
200
|
+
k.cancel();
|
201
|
+
|
202
|
+
ServerSocketChannel server = Acceptors.remove(k.attachment());
|
203
|
+
if (server != null)
|
204
|
+
try{ server.close(); } catch (IOException ex) {};
|
205
|
+
break;
|
206
|
+
}
|
207
|
+
|
208
|
+
try {
|
209
|
+
sn.configureBlocking(false);
|
210
|
+
} catch (IOException e) {
|
211
|
+
e.printStackTrace();
|
212
|
+
continue;
|
213
|
+
}
|
214
|
+
|
215
|
+
b = createBinding();
|
216
|
+
EventableSocketChannel ec = new EventableSocketChannel (sn, b, mySelector, callback);
|
217
|
+
ec.setServerMode();
|
218
|
+
Connections.put (b, ec);
|
219
|
+
NewConnections.add (b);
|
220
|
+
|
221
|
+
callback.trigger(((Long)k.attachment()).longValue(), EventCode.EM_CONNECTION_ACCEPTED, null, b);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
void isReadable (SelectionKey k) {
|
226
|
+
EventableChannel<?> ec = (EventableChannel<?>) k.attachment();
|
227
|
+
if (!ec.read()) {
|
228
|
+
UnboundConnections.add (ec.getBinding());
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
void isWritable (SelectionKey k) {
|
233
|
+
EventableChannel<?> ec = (EventableChannel<?>) k.attachment();
|
234
|
+
if (!ec.write()) {
|
235
|
+
UnboundConnections.add (ec.getBinding());
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
void isConnectable (SelectionKey k) {
|
240
|
+
EventableSocketChannel ec = (EventableSocketChannel) k.attachment();
|
241
|
+
if (!ec.finishConnecting()) {
|
242
|
+
UnboundConnections.add (ec.getBinding());
|
243
|
+
}
|
244
|
+
}
|
245
|
+
|
246
|
+
void close() {
|
247
|
+
try {
|
248
|
+
if (mySelector != null)
|
249
|
+
mySelector.close();
|
250
|
+
} catch (IOException e) {}
|
251
|
+
mySelector = null;
|
252
|
+
|
253
|
+
// run down open connections and sockets.
|
254
|
+
for (ServerSocketChannel c : Acceptors.values()) {
|
255
|
+
try {
|
256
|
+
c.close();
|
257
|
+
} catch (IOException e) {}
|
258
|
+
}
|
259
|
+
|
260
|
+
// 29Sep09: We create an ArrayList of the existing connections, then iterate over
|
261
|
+
// that to call unbind on them. This is because an unbind can trigger a reconnect,
|
262
|
+
// which will add to the Connections HashMap, causing a ConcurrentModificationException.
|
263
|
+
// XXX: The correct behavior here would be to latch the various reactor methods to return
|
264
|
+
// immediately if the reactor is shutting down.
|
265
|
+
ArrayList<EventableChannel<?>> conns = new ArrayList<EventableChannel<?>>();
|
266
|
+
for (EventableChannel<?> ec : Connections.values()) {
|
267
|
+
if (ec != null) {
|
268
|
+
conns.add (ec);
|
269
|
+
}
|
270
|
+
}
|
271
|
+
Connections.clear();
|
272
|
+
|
273
|
+
for (EventableChannel<?> ec : conns) {
|
274
|
+
callback.trigger(ec.getBinding(), EventCode.EM_CONNECTION_UNBOUND, null, (long) 0);
|
275
|
+
ec.close();
|
276
|
+
|
277
|
+
if (!(ec instanceof EventableDatagramChannel)) {
|
278
|
+
EventableSocketChannel sc = (EventableSocketChannel) ec;
|
279
|
+
if (sc != null && sc.isAttached())
|
280
|
+
DetachedConnections.add (sc);
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
for (EventableSocketChannel ec : DetachedConnections) {
|
285
|
+
ec.cleanup();
|
286
|
+
}
|
287
|
+
DetachedConnections.clear();
|
288
|
+
}
|
289
|
+
|
290
|
+
void runLoopbreaks() {
|
291
|
+
if (loopBreaker.getAndSet(false)) {
|
292
|
+
callback.trigger((long) 0, EventCode.EM_LOOPBREAK_SIGNAL, null, (long) 0);
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
296
|
+
public void stop() {
|
297
|
+
bRunReactor = false;
|
298
|
+
signalLoopbreak();
|
299
|
+
}
|
300
|
+
|
301
|
+
void runTimers() {
|
302
|
+
long now = new Date().getTime();
|
303
|
+
while (!Timers.isEmpty()) {
|
304
|
+
long k = Timers.firstKey();
|
305
|
+
if (k > now)
|
306
|
+
break;
|
307
|
+
|
308
|
+
ArrayList<Long> callbacks = Timers.get(k);
|
309
|
+
Timers.remove(k);
|
310
|
+
|
311
|
+
// Fire all timers at this timestamp
|
312
|
+
for (long timerCallback : callbacks) {
|
313
|
+
callback.trigger((long) 0, EventCode.EM_TIMER_FIRED, null, timerCallback);
|
314
|
+
}
|
315
|
+
}
|
316
|
+
}
|
317
|
+
|
318
|
+
public long installOneshotTimer (int milliseconds) {
|
319
|
+
long s = createBinding();
|
320
|
+
long deadline = new Date().getTime() + milliseconds;
|
321
|
+
|
322
|
+
if (Timers.containsKey(deadline)) {
|
323
|
+
Timers.get(deadline).add(s);
|
324
|
+
} else {
|
325
|
+
ArrayList<Long> callbacks = new ArrayList<Long>();
|
326
|
+
callbacks.add(s);
|
327
|
+
Timers.put(deadline, callbacks);
|
328
|
+
}
|
329
|
+
|
330
|
+
return s;
|
331
|
+
}
|
332
|
+
|
333
|
+
public long startTcpServer (SocketAddress sa) throws EmReactorException {
|
334
|
+
try {
|
335
|
+
ServerSocketChannel server = ServerSocketChannel.open();
|
336
|
+
server.configureBlocking(false);
|
337
|
+
server.socket().bind (sa);
|
338
|
+
long s = createBinding();
|
339
|
+
Acceptors.put(s, server);
|
340
|
+
server.register(mySelector, SelectionKey.OP_ACCEPT, s);
|
341
|
+
return s;
|
342
|
+
} catch (IOException e) {
|
343
|
+
throw new EmReactorException ("unable to open socket acceptor: " + e.toString());
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
public long startTcpServer (String address, int port) throws EmReactorException {
|
348
|
+
return startTcpServer (new InetSocketAddress (address, port));
|
349
|
+
}
|
350
|
+
|
351
|
+
public void stopTcpServer (long signature) throws IOException {
|
352
|
+
ServerSocketChannel server = Acceptors.remove(signature);
|
353
|
+
if (server != null)
|
354
|
+
server.close();
|
355
|
+
else
|
356
|
+
throw new RuntimeException ("failed to close unknown acceptor");
|
357
|
+
}
|
358
|
+
|
359
|
+
public long openUdpSocket (InetSocketAddress address) throws IOException {
|
360
|
+
// TODO, don't throw an exception out of here.
|
361
|
+
DatagramChannel dg = DatagramChannel.open();
|
362
|
+
dg.configureBlocking(false);
|
363
|
+
dg.socket().bind(address);
|
364
|
+
long b = createBinding();
|
365
|
+
EventableChannel<?> ec = new EventableDatagramChannel (dg, b, mySelector, callback);
|
366
|
+
dg.register(mySelector, SelectionKey.OP_READ, ec);
|
367
|
+
Connections.put(b, ec);
|
368
|
+
return b;
|
369
|
+
}
|
370
|
+
|
371
|
+
public long openUdpSocket (String address, int port) throws IOException {
|
372
|
+
return openUdpSocket (new InetSocketAddress (address, port));
|
373
|
+
}
|
374
|
+
|
375
|
+
public void sendData (long sig, ByteBuffer bb) throws IOException {
|
376
|
+
Connections.get(sig).scheduleOutboundData( bb );
|
377
|
+
}
|
378
|
+
|
379
|
+
public void sendData (long sig, byte[] data) throws IOException {
|
380
|
+
sendData (sig, ByteBuffer.wrap(data));
|
381
|
+
}
|
382
|
+
|
383
|
+
public void setCommInactivityTimeout (long sig, long mills) {
|
384
|
+
Connections.get(sig).setCommInactivityTimeout (mills);
|
385
|
+
}
|
386
|
+
|
387
|
+
public void sendDatagram (long sig, byte[] data, int length, String recipAddress, int recipPort) {
|
388
|
+
sendDatagram (sig, ByteBuffer.wrap(data), recipAddress, recipPort);
|
389
|
+
}
|
390
|
+
|
391
|
+
public void sendDatagram (long sig, ByteBuffer bb, String recipAddress, int recipPort) {
|
392
|
+
(Connections.get(sig)).scheduleOutboundDatagram( bb, recipAddress, recipPort);
|
393
|
+
}
|
394
|
+
|
395
|
+
public long connectTcpServer (String address, int port) {
|
396
|
+
return connectTcpServer(null, 0, address, port);
|
397
|
+
}
|
398
|
+
|
399
|
+
public long connectTcpServer (String bindAddr, int bindPort, String address, int port) {
|
400
|
+
long b = createBinding();
|
401
|
+
|
402
|
+
try {
|
403
|
+
SocketChannel sc = SocketChannel.open();
|
404
|
+
sc.configureBlocking(false);
|
405
|
+
if (bindAddr != null)
|
406
|
+
sc.socket().bind(new InetSocketAddress (bindAddr, bindPort));
|
407
|
+
|
408
|
+
EventableSocketChannel ec = new EventableSocketChannel (sc, b, mySelector, callback);
|
409
|
+
|
410
|
+
if (sc.connect (new InetSocketAddress (address, port))) {
|
411
|
+
// Connection returned immediately. Can happen with localhost connections.
|
412
|
+
// WARNING, this code is untested due to lack of available test conditions.
|
413
|
+
// Ought to be be able to come here from a localhost connection, but that
|
414
|
+
// doesn't happen on Linux. (Maybe on FreeBSD?)
|
415
|
+
// The reason for not handling this until we can test it is that we
|
416
|
+
// really need to return from this function WITHOUT triggering any EM events.
|
417
|
+
// That's because until the user code has seen the signature we generated here,
|
418
|
+
// it won't be able to properly dispatch them. The C++ EM deals with this
|
419
|
+
// by setting pending mode as a flag in ALL eventable descriptors and making
|
420
|
+
// the descriptor select for writable. Then, it can send UNBOUND and
|
421
|
+
// CONNECTION_COMPLETED on the next pass through the loop, because writable will
|
422
|
+
// fire.
|
423
|
+
throw new RuntimeException ("immediate-connect unimplemented");
|
424
|
+
}
|
425
|
+
else {
|
426
|
+
ec.setConnectPending();
|
427
|
+
Connections.put (b, ec);
|
428
|
+
NewConnections.add (b);
|
429
|
+
}
|
430
|
+
} catch (IOException e) {
|
431
|
+
// Can theoretically come here if a connect failure can be determined immediately.
|
432
|
+
// I don't know how to make that happen for testing purposes.
|
433
|
+
throw new RuntimeException ("immediate-connect unimplemented: " + e.toString());
|
434
|
+
}
|
435
|
+
return b;
|
436
|
+
}
|
437
|
+
|
438
|
+
public void closeConnection (long sig, boolean afterWriting) {
|
439
|
+
EventableChannel<?> ec = Connections.get(sig);
|
440
|
+
if (ec != null)
|
441
|
+
if (ec.scheduleClose (afterWriting))
|
442
|
+
UnboundConnections.add (sig);
|
443
|
+
}
|
444
|
+
|
445
|
+
long createBinding() {
|
446
|
+
return ++BindingIndex;
|
447
|
+
}
|
448
|
+
|
449
|
+
public void signalLoopbreak() {
|
450
|
+
loopBreaker.set(true);
|
451
|
+
if (mySelector != null)
|
452
|
+
mySelector.wakeup();
|
453
|
+
}
|
454
|
+
|
455
|
+
public void setTlsParms(long sig, KeyStore keyStore, boolean verifyPeer) {
|
456
|
+
((EventableSocketChannel) Connections.get(sig)).setTlsParms(keyStore, verifyPeer);
|
457
|
+
}
|
458
|
+
|
459
|
+
public void startTls (long sig) throws NoSuchAlgorithmException, KeyManagementException {
|
460
|
+
Connections.get(sig).startTls();
|
461
|
+
}
|
462
|
+
|
463
|
+
public void acceptSslPeer (long sig) {
|
464
|
+
EventableSocketChannel sc = (EventableSocketChannel) Connections.get(sig);
|
465
|
+
sc.acceptSslPeer();
|
466
|
+
}
|
467
|
+
|
468
|
+
public byte[] getPeerCert (long sig) {
|
469
|
+
EventableSocketChannel sc = (EventableSocketChannel) Connections.get(sig);
|
470
|
+
return sc.getPeerCert();
|
471
|
+
}
|
472
|
+
|
473
|
+
public void setTimerQuantum (int mills) {
|
474
|
+
if (mills < 5 || mills > 2500)
|
475
|
+
throw new RuntimeException ("attempt to set invalid timer-quantum value: "+mills);
|
476
|
+
timerQuantum = mills;
|
477
|
+
}
|
478
|
+
|
479
|
+
public Object[] getPeerName (long sig) {
|
480
|
+
return Connections.get(sig).getPeerName();
|
481
|
+
}
|
482
|
+
|
483
|
+
public Object[] getSockName (long sig) {
|
484
|
+
return Connections.get(sig).getSockName();
|
485
|
+
}
|
486
|
+
|
487
|
+
public long attachChannel (SocketChannel sc, boolean watch_mode) {
|
488
|
+
long b = createBinding();
|
489
|
+
|
490
|
+
EventableSocketChannel ec = new EventableSocketChannel (sc, b, mySelector, callback);
|
491
|
+
|
492
|
+
ec.setAttached();
|
493
|
+
if (watch_mode)
|
494
|
+
ec.setWatchOnly();
|
495
|
+
|
496
|
+
Connections.put (b, ec);
|
497
|
+
NewConnections.add (b);
|
498
|
+
|
499
|
+
return b;
|
500
|
+
}
|
501
|
+
|
502
|
+
public SocketChannel detachChannel (long sig) {
|
503
|
+
EventableSocketChannel ec = (EventableSocketChannel) Connections.get (sig);
|
504
|
+
if (ec != null) {
|
505
|
+
UnboundConnections.add (sig);
|
506
|
+
return ec.getChannel();
|
507
|
+
} else {
|
508
|
+
return null;
|
509
|
+
}
|
510
|
+
}
|
511
|
+
|
512
|
+
public void setNotifyReadable (long sig, boolean mode) {
|
513
|
+
((EventableSocketChannel) Connections.get(sig)).setNotifyReadable(mode);
|
514
|
+
}
|
515
|
+
|
516
|
+
public void setNotifyWritable (long sig, boolean mode) {
|
517
|
+
((EventableSocketChannel) Connections.get(sig)).setNotifyWritable(mode);
|
518
|
+
}
|
519
|
+
|
520
|
+
public boolean isNotifyReadable (long sig) {
|
521
|
+
return Connections.get(sig).isNotifyReadable();
|
522
|
+
}
|
523
|
+
|
524
|
+
public boolean isNotifyWritable (long sig) {
|
525
|
+
return Connections.get(sig).isNotifyWritable();
|
526
|
+
}
|
527
|
+
|
528
|
+
public int getConnectionCount() {
|
529
|
+
return Connections.size() + Acceptors.size();
|
530
|
+
}
|
531
|
+
}
|