Просмотр исходного кода

Listener: Remove the socket event handler when freeing. Use a job for default accepting instead of directly using a dead var.

ambrop7 15 лет назад
Родитель
Сommit
fc2561fa55
2 измененных файлов с 30 добавлено и 37 удалено
  1. 27 30
      system/Listener.c
  2. 3 7
      system/Listener.h

+ 27 - 30
system/Listener.c

@@ -32,22 +32,23 @@
 static void socket_handler (Listener *o, int event)
 static void socket_handler (Listener *o, int event)
 {
 {
     ASSERT(event == BSOCKET_ACCEPT)
     ASSERT(event == BSOCKET_ACCEPT)
+    DebugObject_Access(&o->d_obj);
     
     
-    o->accepted = 0;
+    // schedule accept job (to accept and close the connection in case the handler doesn't)
+    BPending_Set(&o->accept_job);
     
     
-    DebugIn_GoIn(&o->d_in_handler);
-    DEAD_ENTER(o->dead)
+    // call handler
     o->handler(o->user);
     o->handler(o->user);
-    if (DEAD_LEAVE(o->dead)) {
-        return;
-    }
-    DebugIn_GoOut(&o->d_in_handler);
+    return;
+}
+
+static void accept_job_handler (Listener *o)
+{
+    DebugObject_Access(&o->d_obj);
     
     
-    // if there was no attempt to accept, do it now, discarding the client
-    if (!o->accepted) {
-        if (BSocket_Accept(o->sock, NULL, NULL) < 0) {
-            BLog(BLOG_ERROR, "BSocket_Accept failed (%d)", BSocket_GetError(o->sock));
-        }
+    // accept and discard the connection
+    if (BSocket_Accept(o->sock, NULL, NULL) < 0) {
+        BLog(BLOG_ERROR, "BSocket_Accept failed (%d)", BSocket_GetError(o->sock));
     }
     }
 }
 }
 
 
@@ -60,9 +61,6 @@ int Listener_Init (Listener *o, BReactor *reactor, BAddr addr, Listener_handler
     o->handler = handler;
     o->handler = handler;
     o->user = user;
     o->user = user;
     
     
-    // init dead var
-    DEAD_INIT(o->dead);
-    
     // set not existing
     // set not existing
     o->existing = 0;
     o->existing = 0;
     
     
@@ -91,10 +89,9 @@ int Listener_Init (Listener *o, BReactor *reactor, BAddr addr, Listener_handler
     BSocket_AddEventHandler(o->sock, BSOCKET_ACCEPT, (BSocket_handler)socket_handler, o);
     BSocket_AddEventHandler(o->sock, BSOCKET_ACCEPT, (BSocket_handler)socket_handler, o);
     BSocket_EnableEvent(o->sock, BSOCKET_ACCEPT);
     BSocket_EnableEvent(o->sock, BSOCKET_ACCEPT);
     
     
-    // init debug in handler
-    DebugIn_Init(&o->d_in_handler);
+    // init accept job
+    BPending_Init(&o->accept_job, BReactor_PendingGroup(o->reactor), (BPending_handler)accept_job_handler, o);
     
     
-    // init debug object
     DebugObject_Init(&o->d_obj);
     DebugObject_Init(&o->d_obj);
     
     
     return 1;
     return 1;
@@ -113,9 +110,6 @@ void Listener_InitExisting (Listener *o, BReactor *reactor, BSocket *sock, Liste
     o->user = user;
     o->user = user;
     o->sock = sock;
     o->sock = sock;
     
     
-    // init dead var
-    DEAD_INIT(o->dead);
-    
     // set existing
     // set existing
     o->existing = 1;
     o->existing = 1;
     
     
@@ -123,33 +117,36 @@ void Listener_InitExisting (Listener *o, BReactor *reactor, BSocket *sock, Liste
     BSocket_AddEventHandler(o->sock, BSOCKET_ACCEPT, (BSocket_handler)socket_handler, o);
     BSocket_AddEventHandler(o->sock, BSOCKET_ACCEPT, (BSocket_handler)socket_handler, o);
     BSocket_EnableEvent(o->sock, BSOCKET_ACCEPT);
     BSocket_EnableEvent(o->sock, BSOCKET_ACCEPT);
     
     
-    // init debug in handler
-    DebugIn_Init(&o->d_in_handler);
+    // init accept job
+    BPending_Init(&o->accept_job, BReactor_PendingGroup(o->reactor), (BPending_handler)accept_job_handler, o);
     
     
-    // init debug object
     DebugObject_Init(&o->d_obj);
     DebugObject_Init(&o->d_obj);
 }
 }
 
 
 void Listener_Free (Listener *o)
 void Listener_Free (Listener *o)
 {
 {
-    // free debug object
     DebugObject_Free(&o->d_obj);
     DebugObject_Free(&o->d_obj);
     
     
+    // free accept job
+    BPending_Free(&o->accept_job);
+    
+    // remove socket event handler
+    BSocket_RemoveEventHandler(o->sock, BSOCKET_ACCEPT);
+    
     if (!o->existing) {
     if (!o->existing) {
         // free socket
         // free socket
         BSocket_Free(&o->our_sock);
         BSocket_Free(&o->our_sock);
     }
     }
-    
-    // free dead var
-    DEAD_KILL(o->dead);
 }
 }
 
 
 int Listener_Accept (Listener *o, BSocket *sockout, BAddr *addrout)
 int Listener_Accept (Listener *o, BSocket *sockout, BAddr *addrout)
 {
 {
     ASSERT(sockout)
     ASSERT(sockout)
-    ASSERT(DebugIn_In(&o->d_in_handler))
+    ASSERT(BPending_IsSet(&o->accept_job))
+    DebugObject_Access(&o->d_obj);
     
     
-    o->accepted = 1;
+    // unset accept job
+    BPending_Unset(&o->accept_job);
     
     
     if (BSocket_Accept(o->sock, sockout, addrout) < 0) {
     if (BSocket_Accept(o->sock, sockout, addrout) < 0) {
         BLog(BLOG_ERROR, "BSocket_Accept failed (%d)", BSocket_GetError(o->sock));
         BLog(BLOG_ERROR, "BSocket_Accept failed (%d)", BSocket_GetError(o->sock));

+ 3 - 7
system/Listener.h

@@ -27,9 +27,6 @@
 #ifndef BADVPN_SYSTEM_LISTENER_H
 #ifndef BADVPN_SYSTEM_LISTENER_H
 #define BADVPN_SYSTEM_LISTENER_H
 #define BADVPN_SYSTEM_LISTENER_H
 
 
-#include <misc/dead.h>
-#include <misc/debugcounter.h>
-#include <misc/debugin.h>
 #include <system/DebugObject.h>
 #include <system/DebugObject.h>
 #include <system/BSocket.h>
 #include <system/BSocket.h>
 
 
@@ -48,15 +45,13 @@ typedef void (*Listener_handler) (void *user);
  * Object used to listen on a socket and accept clients.
  * Object used to listen on a socket and accept clients.
  */
  */
 typedef struct {
 typedef struct {
-    dead_t dead;
     BReactor *reactor;
     BReactor *reactor;
     int existing;
     int existing;
     BSocket our_sock;
     BSocket our_sock;
     BSocket *sock;
     BSocket *sock;
     Listener_handler handler;
     Listener_handler handler;
     void *user;
     void *user;
-    int accepted;
-    DebugIn d_in_handler;
+    BPending accept_job;
     DebugObject d_obj;
     DebugObject d_obj;
 } Listener;
 } Listener;
 
 
@@ -94,7 +89,8 @@ void Listener_Free (Listener *o);
 
 
 /**
 /**
  * Accepts a connection.
  * Accepts a connection.
- * Must be called from within the {@link Listener_handler} handler.
+ * Must be called from within the {@link Listener_handler} handler or its jobs, and
+ * at most once.
  * 
  * 
  * @param o the object
  * @param o the object
  * @param sockout uninitialized {@link BSocket} structure to put the new socket in.
  * @param sockout uninitialized {@link BSocket} structure to put the new socket in.