]> code.citadel.org Git - citadel.git/blobdiff - citadel/event_client.c
Instead of initiating the transition between DB & IO-Queue from within the applicatio...
[citadel.git] / citadel / event_client.c
index 7903563c55c9d9ab905af21846b4d779c15a2375..bdb33dd735f347dae83c400643d06c30be674fec 100644 (file)
@@ -18,6 +18,9 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#if HAVE_BACKTRACE
+#include <execinfo.h>
+#endif
 
 #include <libcitadel.h>
 
@@ -83,7 +86,7 @@ extern struct ev_loop *event_db;
 extern ev_async DBAddJob;
 extern ev_async DBExitEventLoop;
 
-eNextState QueueDBOperation(AsyncIO *IO, IO_CallBack CB)
+eNextState QueueAnDBOperation(AsyncIO *IO)
 {
        IOAddHandler *h;
        int i;
@@ -91,7 +94,10 @@ eNextState QueueDBOperation(AsyncIO *IO, IO_CallBack CB)
        SetEVState(IO, eDBQ);
        h = (IOAddHandler*)malloc(sizeof(IOAddHandler));
        h->IO = IO;
-       h->EvAttch = CB;
+
+       assert(IO->ReAttachCB != NULL);
+
+       h->EvAttch = IO->ReAttachCB;
        ev_cleanup_init(&IO->db_abort_by_shutdown,
                        IO_abort_shutdown_callback);
        IO->db_abort_by_shutdown.data = IO;
@@ -119,7 +125,7 @@ eNextState QueueDBOperation(AsyncIO *IO, IO_CallBack CB)
        ev_async_send (event_db, &DBAddJob);
        pthread_mutex_unlock(&DBEventExitQueueMutex);
 
-       EVM_syslog(LOG_DEBUG, "DBEVENT Q Done.\n");
+       EVQM_syslog(LOG_DEBUG, "DBEVENT Q Done.\n");
        return eDBQuery;
 }
 
@@ -216,7 +222,7 @@ static void IO_abort_shutdown_callback(struct ev_loop *loop,
 }
 
 
-eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB)
+eNextState QueueAnEventContext(AsyncIO *IO)
 {
        IOAddHandler *h;
        int i;
@@ -224,7 +230,11 @@ eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB)
        SetEVState(IO, eIOQ);
        h = (IOAddHandler*)malloc(sizeof(IOAddHandler));
        h->IO = IO;
-       h->EvAttch = CB;
+
+       assert(IO->ReAttachCB != NULL);
+
+       h->EvAttch = IO->ReAttachCB;
+
        ev_cleanup_init(&IO->abort_by_shutdown,
                        IO_abort_shutdown_callback);
        IO->abort_by_shutdown.data = IO;
@@ -254,15 +264,23 @@ eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB)
        return eSendReply;
 }
 
-eNextState EventQueueDBOperation(AsyncIO *IO, IO_CallBack CB)
+eNextState EventQueueDBOperation(AsyncIO *IO, IO_CallBack CB, int CloseFDs)
 {
-       StopClientWatchers(IO, 0);
-       return QueueDBOperation(IO, CB);
+       StopClientWatchers(IO, CloseFDs);
+       IO->ReAttachCB = CB;
+       return eDBQuery;
 }
 eNextState DBQueueEventContext(AsyncIO *IO, IO_CallBack CB)
 {
        StopDBWatchers(IO);
-       return QueueEventContext(IO, CB);
+       IO->ReAttachCB = CB;
+       return eSendReply;
+}
+
+eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB)
+{
+       IO->ReAttachCB = CB;
+       return QueueAnEventContext(IO);
 }
 
 extern eNextState evcurl_handle_start(AsyncIO *IO);
@@ -307,11 +325,11 @@ eNextState QueueCurlContext(AsyncIO *IO)
 eNextState CurlQueueDBOperation(AsyncIO *IO, IO_CallBack CB)
 {
        StopCurlWatchers(IO);
-       return QueueDBOperation(IO, CB);
+       IO->ReAttachCB = CB;
+       return eDBQuery;
 }
 
 
-void DestructCAres(AsyncIO *IO);
 void FreeAsyncIOContents(AsyncIO *IO)
 {
        CitContext *Ctx = IO->CitContext;
@@ -320,8 +338,6 @@ void FreeAsyncIOContents(AsyncIO *IO)
        FreeStrBuf(&IO->SendBuf.Buf);
        FreeStrBuf(&IO->RecvBuf.Buf);
 
-       DestructCAres(IO);
-
        FreeURL(&IO->ConnectMe);
        FreeStrBuf(&IO->HttpReq.ReplyData);
 
@@ -333,8 +349,13 @@ void FreeAsyncIOContents(AsyncIO *IO)
 }
 
 
+void DestructCAres(AsyncIO *IO);
 void StopClientWatchers(AsyncIO *IO, int CloseFD)
 {
+       EVM_syslog(LOG_DEBUG, "EVENT StopClientWatchers");
+       
+       DestructCAres(IO);
+
        ev_timer_stop (event_base, &IO->rw_timeout);
        ev_timer_stop(event_base, &IO->conn_fail);
        ev_idle_stop(event_base, &IO->unwind_stack);
@@ -488,10 +509,17 @@ eReadState HandleInbound(AsyncIO *IO)
                }
 
                if (Finished != eMustReadMore) {
+                       eNextState rc;
                        assert(IO->ReadDone);
                        ev_io_stop(event_base, &IO->recv_event);
-                       IO->NextState = IO->ReadDone(IO);
-                       Finished = StrBufCheckBuffer(&IO->RecvBuf);
+                       rc = IO->ReadDone(IO);
+                       if  (rc == eDBQuery) {
+                               return QueueAnDBOperation(IO);
+                       }
+                       else {
+                               IO->NextState = rc;
+                               Finished = StrBufCheckBuffer(&IO->RecvBuf);
+                       }
                }
        }
 
@@ -1226,10 +1254,12 @@ void KillAsyncIOContext(AsyncIO *IO)
        case eReadMore:
        case eReadPayload:
        case eReadFile:
-               QueueEventContext(&Ctx->IO, KillOtherContextNow);
+               IO->ReAttachCB = KillOtherContextNow;
+               QueueAnEventContext(&Ctx->IO);
                break;
        case eDBQuery:
-               QueueDBOperation(&Ctx->IO, KillOtherContextNow);
+               IO->ReAttachCB = KillOtherContextNow;
+               QueueAnDBOperation(&Ctx->IO);
                break;
        case eTerminateConnection:
        case eAbort: