gnash-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnash-dev] invoke the XMLSocket.onClose() callback


From: Ching-Yi Chan
Subject: Re: [Gnash-dev] invoke the XMLSocket.onClose() callback
Date: Fri, 29 May 2009 01:45:50 +0800

I found a solution to detect the socket is disconnected by remote.
Using recv function with MSG_PEEK flag can test our socket fd is good or bad.
When socket fd is bad, system will send SIGPIG signal and do something such as terminating application, set external errno vaiable to EPIPE. I write errno_sample.c to prove this concept (see attachments).

Do a few modification, let the XmlSocketServer.pl can disconnection the client socket when receive the "<eof/>" message, we can test the disconnection situation.

Test 1:
1.1 start server:
    perl XmlSocketServer.pl

1.2 compile errno_sample.c and run client
    gcc errno_sample.c -o client
    ./client

the output is:
[CONNECT] ret: 0, err: 0
[SELECT] ret: 0, err: 0
[RECV] ret: 3, err: 0
[SELECT] ret: 1, err: 0
[RECV] ret: 3, err: 0
[SELECT] ret: 1, err: 0
[RECV] ret: 6, err: 0
[SELECT] ret: 1, err: 0
[RECV] ret: 9, err: 0
sent close message
[SELECT] ret: 1, err: 0
[RECV] ret: 12, err: 0
sent close message
[SELECT] ret: 1, err: 32
[RECV] ret: 22, err: 32

client will send "<eof/> to server.
if server is close connection, client receive the errno EPIPE(32) and stop itself.

=============================================================================================

use the same implement to add SocketConnection.lostConnection() method

=== modified file 'libcore/asobj/XMLSocket_as.cpp'
--- libcore/asobj/XMLSocket_as.cpp    2009-05-18 14:27:16 +0000
+++ libcore/asobj/XMLSocket_as.cpp    2009-05-26 19:38:25 +0000
@@ -38,6 +38,8 @@
 #include <boost/scoped_array.hpp>
 #include <boost/scoped_ptr.hpp>
 #include <string>
+#include <errno.h>
+#include <signal.h>
 
 #undef GNASH_XMLSOCKET_DEBUG
 
@@ -97,6 +99,15 @@
         _complete = true;
     }
 
+    bool lostConnection(){
+    char buf[10];
+    signal(SIGPIPE, SIG_IGN);
+    int r = recv(_socket.getFileFd(), buf, sizeof buf, MSG_PEEK);
+    log_debug(_("errno at lost connection, read: %d, err: %d"), r, errno);
+    signal(SIGPIPE, SIG_DFL);
+    return errno == EPIPE;
+    }
+
     size_t writeMessage(const std::string& str) {
         // We have to write the null terminator as well.
         return write(_socket.getFileFd(), str.c_str(), str.size() + 1);
@@ -293,6 +304,7 @@
     // Wait until something has happened with the connection
     if (!_connection.complete()) return;
    
+
     // If this XMLSocket hadn't finished a connection, check whether it
     // has now.
     if (!ready()) {
@@ -312,6 +324,13 @@
         _ready = true;
     }
 
+    if(_connection.lostConnection()){
+    log_debug(_("call onClose"));
+    callMethod(NSV::PROP_ON_CLOSE);
+    _vm.getRoot().removeAdvanceCallback(this);
+    return;
+    }
+
     // Now the connection is established we can receive data.
     checkForIncomingData();
 }

and test the lost connection situation


test 2.
2.1 make && make install
2.2 run gnash

but no EPIPE errno received. the debug log said the EAGAIN(11) errno instead

2634:1] 01:28:51 DEBUG: errno at lost connection, read: 0, err: 11
2634:1] 01:28:51 DEBUG: errno at lost connection, read: 0, err: 11
2634:1] 01:28:51 DEBUG: errno at lost connection, read: 0, err: 11

PS. test 2. we use the simple_server.c because of the modified XmlSocketServer.pl made XMLSocket connection failed. However, I am not familier with perl and have no idea to fix it.

Maybe I misunderstand something, please give me some information.

Attachment: XmlSocketServer.pl
Description: Text Data

Attachment: errno_sample.c
Description: Text Data

Attachment: DisConnectionSample.swf
Description: application/shockwave-flash

Attachment: simple_server.c
Description: Text Data

Attachment: bzr.diff
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]