Skip to content

Commit 7beea2c

Browse files
committed
Upgrade evcom; Add setTimeout method to node.tcp.Connection
The default timeout is 60 seconds, but it can now be changed. evcom upgrade includes fixes to force_close.
1 parent 18a1923 commit 7beea2c

File tree

8 files changed

+169
-33
lines changed

8 files changed

+169
-33
lines changed

deps/evcom/evcom.c

+39-19
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ stream__handshake (evcom_stream *stream)
392392
return OKAY;
393393
}
394394

395-
evcom_stream_reset_timeout(stream);
395+
ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
396396

397397
if (r == GNUTLS_E_INTERRUPTED || r == GNUTLS_E_AGAIN) {
398398
if (0 == gnutls_record_get_direction((stream)->session)) {
@@ -411,11 +411,14 @@ stream__handshake (evcom_stream *stream)
411411
stream->flags |= EVCOM_CONNECTED;
412412
if (stream->on_connect) stream->on_connect(stream);
413413

414-
ev_io_start(D_LOOP_(stream) &stream->read_watcher);
415-
ev_io_start(D_LOOP_(stream) &stream->write_watcher);
414+
/* evcom_stream_force_close might have been called. */
415+
if (stream->recvfd >= 0 && stream->sendfd >= 0) {
416+
ev_io_start(D_LOOP_(stream) &stream->read_watcher);
417+
ev_io_start(D_LOOP_(stream) &stream->write_watcher);
416418

417-
stream->send_action = stream_send__data;
418-
stream->recv_action = stream_recv__data;
419+
stream->send_action = stream_send__data;
420+
stream->recv_action = stream_recv__data;
421+
}
419422

420423
return OKAY;
421424
}
@@ -541,7 +544,7 @@ stream_recv__data (evcom_stream *stream)
541544
return OKAY;
542545
}
543546

544-
evcom_stream_reset_timeout(stream);
547+
ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
545548

546549
assert(recved >= 0);
547550

@@ -614,7 +617,7 @@ stream_send__data (evcom_stream *stream)
614617
return OKAY;
615618
}
616619

617-
evcom_stream_reset_timeout(stream);
620+
ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
618621

619622
assert(sent >= 0);
620623

@@ -638,14 +641,24 @@ stream_send__shutdown (evcom_stream *stream)
638641
int r = shutdown(stream->sendfd, SHUT_WR);
639642

640643
if (r < 0) {
641-
stream->errorno = errno;
642-
evcom_perror("shutdown()", errno);
644+
switch (errno) {
645+
case EINTR:
646+
assert(stream->send_action == stream_send__shutdown);
647+
return OKAY;
648+
649+
case ENOTCONN:
650+
break;
651+
652+
default:
653+
stream->errorno = errno;
654+
evcom_perror("shutdown()", errno);
655+
break;
656+
}
643657
stream->send_action = stream_send__close;
644658
return OKAY;
645659
}
646660

647661
stream->flags &= ~EVCOM_WRITABLE;
648-
649662
stream->send_action = stream_send__wait_for_eof;
650663
return OKAY;
651664
}
@@ -985,13 +998,15 @@ on_timeout (EV_P_ ev_timer *watcher, int revents)
985998
assert(watcher == &stream->timeout_watcher);
986999

9871000
if (PAUSED(stream)) {
988-
evcom_stream_reset_timeout(stream);
1001+
ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
9891002
return;
9901003
}
9911004

9921005
if (stream->on_timeout) stream->on_timeout(stream);
9931006

9941007
evcom_stream_force_close(stream);
1008+
1009+
if (stream->on_close) stream->on_close(stream);
9951010
}
9961011

9971012
static void
@@ -1045,7 +1060,7 @@ stream_event (EV_P_ ev_io *w, int revents)
10451060
* gnutls_db_set_ptr (stream->session, _);
10461061
*/
10471062
void
1048-
evcom_stream_init (evcom_stream *stream, float timeout)
1063+
evcom_stream_init (evcom_stream *stream)
10491064
{
10501065
stream->flags = 0;
10511066
stream->errorno = 0;
@@ -1069,7 +1084,7 @@ evcom_stream_init (evcom_stream *stream, float timeout)
10691084
stream->gnutls_errorno = 0;
10701085
stream->session = NULL;
10711086
#endif
1072-
ev_timer_init(&stream->timeout_watcher, on_timeout, 0., timeout);
1087+
ev_timer_init(&stream->timeout_watcher, on_timeout, 0., 60.);
10731088
stream->timeout_watcher.data = stream;
10741089

10751090
stream->on_connect = NULL;
@@ -1098,8 +1113,8 @@ void evcom_stream_force_close (evcom_stream *stream)
10981113

10991114
if (!DUPLEX(stream) && stream->sendfd >= 0) {
11001115
close(stream->sendfd);
1101-
stream__set_send_closed(stream);
11021116
}
1117+
stream__set_send_closed(stream);
11031118

11041119
evcom_stream_detach(stream);
11051120
}
@@ -1175,9 +1190,12 @@ evcom_stream_write (evcom_stream *stream, const char *str, size_t len)
11751190
}
11761191

11771192
void
1178-
evcom_stream_reset_timeout (evcom_stream *stream)
1193+
evcom_stream_reset_timeout (evcom_stream *stream, float timeout)
11791194
{
1180-
ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
1195+
stream->timeout_watcher.repeat = timeout;
1196+
if (ATTACHED(stream)) {
1197+
ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
1198+
}
11811199
}
11821200

11831201
void
@@ -1211,6 +1229,7 @@ void
12111229
evcom_stream_read_pause (evcom_stream *stream)
12121230
{
12131231
stream->flags |= EVCOM_PAUSED;
1232+
ev_timer_stop(D_LOOP_(stream) &stream->timeout_watcher);
12141233
if (stream->recv_action == stream_recv__data) {
12151234
ev_io_stop(D_LOOP_(stream) &stream->read_watcher);
12161235
stream->recv_action = stream_recv__wait_for_resume;
@@ -1221,12 +1240,13 @@ void
12211240
evcom_stream_read_resume (evcom_stream *stream)
12221241
{
12231242
stream->flags &= ~EVCOM_PAUSED;
1224-
evcom_stream_reset_timeout(stream);
1243+
ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
12251244
if (stream->recv_action == stream_recv__wait_for_resume) {
12261245
stream->recv_action = stream_recv__data;
12271246
}
1228-
if (ATTACHED(stream) && READABLE(stream)) {
1229-
ev_io_start(D_LOOP_(stream) &stream->read_watcher);
1247+
if (ATTACHED(stream)) {
1248+
ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
1249+
if (READABLE(stream)) ev_io_start(D_LOOP_(stream) &stream->read_watcher);
12301250
}
12311251
}
12321252

deps/evcom/evcom.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ void evcom_server_attach (EV_P_ evcom_server *);
181181
void evcom_server_detach (evcom_server *);
182182
void evcom_server_close (evcom_server *);
183183

184-
void evcom_stream_init (evcom_stream *, float timeout);
184+
void evcom_stream_init (evcom_stream *);
185185

186186
int evcom_stream_pair (evcom_stream *a, evcom_stream *b);
187187
int evcom_stream_connect (evcom_stream *, struct sockaddr *address);
@@ -191,8 +191,7 @@ void evcom_stream_attach (EV_P_ evcom_stream *);
191191
void evcom_stream_detach (evcom_stream *);
192192
void evcom_stream_read_resume (evcom_stream *);
193193
void evcom_stream_read_pause (evcom_stream *);
194-
/* Resets the timeout to stay alive for another stream->timeout seconds */
195-
void evcom_stream_reset_timeout (evcom_stream *);
194+
void evcom_stream_reset_timeout (evcom_stream *, float timeout);
196195
void evcom_stream_write (evcom_stream *, const char *str, size_t len);
197196
/* Once the write buffer is drained, evcom_stream_close will shutdown the
198197
* writing end of the stream and will close the read end once the server

deps/evcom/test/echo.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@ on_server_connection (evcom_server *server, struct sockaddr *addr)
5858
assert(addr);
5959

6060
evcom_stream *stream = malloc(sizeof(evcom_stream));
61-
evcom_stream_init(stream, TIMEOUT);
61+
evcom_stream_init(stream);
6262
stream->on_read = on_peer_read;
6363
stream->on_close = on_peer_close;
6464
stream->on_timeout = on_peer_timeout;
65+
evcom_stream_reset_timeout(stream, TIMEOUT);
6566

6667
nconnections++;
6768

deps/evcom/test/test.c

+16-8
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,11 @@ pingpong_on_server_connection (evcom_server *_server, struct sockaddr *addr)
155155
assert(addr);
156156

157157
evcom_stream *stream = malloc(sizeof(evcom_stream));
158-
evcom_stream_init(stream, PINGPONG_TIMEOUT);
158+
evcom_stream_init(stream);
159159
stream->on_read = pingpong_on_peer_read;
160160
stream->on_close = common_on_peer_close;
161161
stream->on_timeout = common_on_peer_timeout;
162+
evcom_stream_reset_timeout(stream, PINGPONG_TIMEOUT);
162163

163164
assert(EVCOM_INITIALIZED == evcom_stream_state(stream));
164165

@@ -226,11 +227,12 @@ pingpong (struct sockaddr *address)
226227
assert(r == 0);
227228
evcom_server_attach(EV_DEFAULT_ &server);
228229

229-
evcom_stream_init(&client, PINGPONG_TIMEOUT);
230+
evcom_stream_init(&client);
230231
client.on_read = pingpong_on_client_read;
231232
client.on_connect = pingpong_on_client_connect;
232233
client.on_close = pingpong_on_client_close;
233234
client.on_timeout = common_on_client_timeout;
235+
evcom_stream_reset_timeout(&client, PINGPONG_TIMEOUT);
234236

235237
assert(EVCOM_INITIALIZED == evcom_stream_state(&client));
236238

@@ -274,10 +276,11 @@ connint_on_connection(evcom_server *_server, struct sockaddr *addr)
274276
assert(addr);
275277

276278
evcom_stream *stream = malloc(sizeof(evcom_stream));
277-
evcom_stream_init(stream, CONNINT_TIMEOUT);
279+
evcom_stream_init(stream);
278280
stream->on_read = send_bye_and_close;
279281
stream->on_close = common_on_peer_close;
280282
stream->on_timeout = common_on_peer_timeout;
283+
evcom_stream_reset_timeout(stream, CONNINT_TIMEOUT);
281284

282285
#if EVCOM_HAVE_GNUTLS
283286
if (use_tls) anon_tls_server(stream);
@@ -349,11 +352,12 @@ connint (struct sockaddr *address)
349352
int i;
350353
for (i = 0; i < NCONN; i++) {
351354
evcom_stream *client = &clients[i];
352-
evcom_stream_init(client, CONNINT_TIMEOUT);
355+
evcom_stream_init(client);
353356
client->on_read = connint_on_client_read;
354357
client->on_connect = connint_on_client_connect;
355358
client->on_close = connint_on_client_close;
356359
client->on_timeout = common_on_client_timeout;
360+
evcom_stream_reset_timeout(client, CONNINT_TIMEOUT);
357361
#if EVCOM_HAVE_GNUTLS
358362
if (use_tls) anon_tls_client(client);
359363
#endif
@@ -554,18 +558,20 @@ pair_pingpong (int use_pipe)
554558
b_got_connect = 0;
555559
pair_pingpong_cnt = 0;
556560

557-
evcom_stream_init(&a, PAIR_PINGPONG_TIMEOUT);
561+
evcom_stream_init(&a);
558562
a.on_close = a_close;
559563
a.on_connect = a_connect;
560564
a.on_read = a_read;
565+
evcom_stream_reset_timeout(&a, PAIR_PINGPONG_TIMEOUT);
561566
#if EVCOM_HAVE_GNUTLS
562567
if (use_tls) anon_tls_client(&a);
563568
#endif
564569

565-
evcom_stream_init(&b, PAIR_PINGPONG_TIMEOUT);
570+
evcom_stream_init(&b);
566571
b.on_close = b_close;
567572
b.on_connect = b_connect;
568573
b.on_read = b_read;
574+
evcom_stream_reset_timeout(&b, PAIR_PINGPONG_TIMEOUT);
569575
#if EVCOM_HAVE_GNUTLS
570576
if (use_tls) anon_tls_server(&b);
571577
#endif
@@ -639,10 +645,11 @@ make_echo_connection (evcom_server *server, struct sockaddr *addr)
639645
assert(addr);
640646

641647
evcom_stream *stream = malloc(sizeof(evcom_stream));
642-
evcom_stream_init(stream, ZERO_TIMEOUT);
648+
evcom_stream_init(stream);
643649
stream->on_read = echo;
644650
stream->on_close = free_stream;
645651
stream->on_timeout = error_out;
652+
evcom_stream_reset_timeout(stream, ZERO_TIMEOUT);
646653

647654
#if EVCOM_HAVE_GNUTLS
648655
if (use_tls) anon_tls_server(stream);
@@ -717,11 +724,12 @@ zero_stream (struct sockaddr *address, size_t to_write)
717724
evcom_server_attach(EV_DEFAULT_ &server);
718725

719726
evcom_stream client;
720-
evcom_stream_init(&client, ZERO_TIMEOUT);
727+
evcom_stream_init(&client);
721728
client.on_read = zero_recv;
722729
client.on_connect = zero_start;
723730
client.on_close = zero_close;
724731
client.on_timeout = error_out;
732+
evcom_stream_reset_timeout(&client, ZERO_TIMEOUT);
725733
#if EVCOM_HAVE_GNUTLS
726734
if (use_tls) anon_tls_client(&client);
727735
#endif

src/net.cc

+17-2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Connection::Initialize (v8::Handle<v8::Object> target)
6666
NODE_SET_PROTOTYPE_METHOD(constructor_template, "setEncoding", SetEncoding);
6767
NODE_SET_PROTOTYPE_METHOD(constructor_template, "readPause", ReadPause);
6868
NODE_SET_PROTOTYPE_METHOD(constructor_template, "readResume", ReadResume);
69+
NODE_SET_PROTOTYPE_METHOD(constructor_template, "setTimeout", SetTimeout);
6970

7071
constructor_template->PrototypeTemplate()->SetAccessor(
7172
READY_STATE_SYMBOL,
@@ -104,8 +105,7 @@ void
104105
Connection::Init (void)
105106
{
106107
resolving_ = false;
107-
double timeout = 60.0; // default
108-
evcom_stream_init(&stream_, timeout);
108+
evcom_stream_init(&stream_);
109109
stream_.on_connect = Connection::on_connect;
110110
stream_.on_read = Connection::on_read;
111111
stream_.on_close = Connection::on_close;
@@ -333,6 +333,21 @@ Connection::ReadResume (const Arguments& args)
333333
return Undefined();
334334
}
335335

336+
Handle<Value>
337+
Connection::SetTimeout (const Arguments& args)
338+
{
339+
HandleScope scope;
340+
341+
Connection *connection = ObjectWrap::Unwrap<Connection>(args.This());
342+
assert(connection);
343+
344+
float timeout = (float)(args[0]->IntegerValue()) / 1000;
345+
346+
connection->SetTimeout(timeout);
347+
348+
return Undefined();
349+
}
350+
336351
Handle<Value>
337352
Connection::Close (const Arguments& args)
338353
{

src/net.h

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Connection : public EventEmitter {
2828
static v8::Handle<v8::Value> SetEncoding (const v8::Arguments& args);
2929
static v8::Handle<v8::Value> ReadPause (const v8::Arguments& args);
3030
static v8::Handle<v8::Value> ReadResume (const v8::Arguments& args);
31+
static v8::Handle<v8::Value> SetTimeout (const v8::Arguments& args);
3132

3233
static v8::Handle<v8::Value> ReadyStateGetter (v8::Local<v8::String> _,
3334
const v8::AccessorInfo& info);
@@ -51,6 +52,10 @@ class Connection : public EventEmitter {
5152
void ForceClose (void) { evcom_stream_force_close(&stream_); }
5253
void ReadPause (void) { evcom_stream_read_pause(&stream_); }
5354
void ReadResume (void) { evcom_stream_read_resume(&stream_); }
55+
void SetTimeout (float timeout)
56+
{
57+
evcom_stream_reset_timeout(&stream_, timeout);
58+
}
5459

5560
virtual void OnConnect (void);
5661
virtual void OnReceive (const void *buf, size_t len);

0 commit comments

Comments
 (0)