Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

I have added 'connected' method to Feersum::Connection::Handle #11

Closed
wants to merge 3 commits into from

2 participants

luben Jeremy Stashewsky
luben
luben commented July 12, 2011

It is standard feature for socket handles. I find it useful in order to clean up connections closed from clients. It is meaningful only on write handles but I do not know how to make work only on writers.

Jeremy Stashewsky
Owner
stash commented July 13, 2011

Hi,

Thanks for sending me a pull request! :)

Even though getpeername() can result in ENOTCONN, I'm pretty sure that the only reliable way to test if a socket is "connected" is to try write to it and detect EPIPE/ENOTCONN/etc. That being said, if you know that getpeername() works cross-platform and can point me to some documentation, I'd stand happily corrected.

If you could also add unit tests and documentation to Feersum::Connection::Handle, I'd appreciate it.

Cheers,
~stash

luben
luben commented July 13, 2011

I have looked in IO::Socket and it uses getpeername. This does not detect sockets in CLOSE_WAIT state but detects sockets that look like this in lsof output:

perl 5455 nobody 2183u sock 0,5 0t0 122379659 can't identify protocol

I suspect that after some time (tcp timeout maybe) sockets in CLOSE_WAIT state are closed and not associated with TCP any more.

I have tried another approach: use recv with MSG_PEEK in order to see if the socket is in CLOSE_WAIT state. It works but I am not sure how cross-platform it is. Also the current approach with getpeername is consistent with IO::Socket so it is least surprising option.

I will write docs for the feature. Also I will write test for the connected state, it will be difficult to test disconnected state.

I will ping you with another pull request for docs and tests.

Best regards
luben

luben
luben commented July 13, 2011

I have added the test and documentation.

luben luben closed this July 13, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
18  Feersum.xs
@@ -2511,6 +2511,24 @@ seek (feer_conn_handle *hdl, ssize_t offset, ...)
2511 2511
         RETVAL
2512 2512
 
2513 2513
 int
  2514
+connected (feer_conn_handle *hdl)
  2515
+    PROTOTYPE: $
  2516
+    CODE:
  2517
+{
  2518
+    assert(ix);
  2519
+    socklen_t addrlen;
  2520
+    int res;
  2521
+    res = getpeername(hdl->fd, hdl->sa, &addrlen);
  2522
+    if (res == 0) {
  2523
+        RETVAL = 1;
  2524
+    } else {
  2525
+        RETVAL = 0;
  2526
+    }
  2527
+}
  2528
+    OUTPUT:
  2529
+        RETVAL
  2530
+
  2531
+int
2514 2532
 close (feer_conn_handle *hdl)
2515 2533
     PROTOTYPE: $
2516 2534
     ALIAS:
9  lib/Feersum/Connection/Handle.pm
@@ -57,6 +57,8 @@ For write handles:
57 57
     $w->poll_cb(sub {
58 58
         # use $_[0] instead of $w to avoid a closure
59 59
         $_[0]->write(\"some data");
  60
+        # check if the socket is connected
  61
+        $_[0]->connected();
60 62
         # can close() or unregister the poll_cb in here
61 63
         $_[0]->close();
62 64
     });
@@ -138,6 +140,13 @@ Pass in an array-ref and it works much like the two C<write()> calls above,
138 140
 except it's way more efficient than calling C<write()> over and over.
139 141
 Undefined elements of the array are ignored.
140 142
 
  143
+=item C<< $w->connected() >>
  144
+
  145
+Uses getpeername in order to determine if the underlying socket is connected.
  146
+It will return true even if the socket is in CLOSE_WAIT state. If the TCP 
  147
+socket is closed (after TCP timeout) by the system it will return false 
  148
+value. The implementations is consistent with IO::Handle.
  149
+
141 150
 =item C<< $w->close() >>
142 151
 
143 152
 Close the HTTP response (which triggers the "T-E: chunked" terminating chunk
3  t/05-streaming.t
@@ -5,7 +5,7 @@ use constant HARDER => $ENV{RELEASE_TESTING} ? 10 : 1;
5 5
 use constant CLIENTS_11 => HARDER * 2;
6 6
 use constant CLIENTS_10 => HARDER * 2;
7 7
 use constant CLIENTS => CLIENTS_11 + CLIENTS_10;
8  
-use Test::More tests => 7 + 21 * CLIENTS_11 + 22 * CLIENTS_10;
  8
+use Test::More tests => 7 + 22 * CLIENTS_11 + 23 * CLIENTS_10;
9 9
 use Test::Fatal;
10 10
 use lib 't'; use Utils;
11 11
 
@@ -45,6 +45,7 @@ $evh->request_handler(sub {
45 45
     $started++;
46 46
     isa_ok($w, 'Feersum::Connection::Writer', "got a writer $cnum");
47 47
     isa_ok($w, 'Feersum::Connection::Handle', "... it's a handle $cnum");
  48
+    ok $w->connected, "connected method works on write handle";
48 49
     my $n = 0;
49 50
     my $wrote_third = 0;
50 51
     my $t; $t = AE::timer rand()/5,rand()/5, sub {
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.