]> 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 68995ddf7153401a26f8aa7222285959b33f16ca..bdb33dd735f347dae83c400643d06c30be674fec 100644 (file)
@@ -9,61 +9,23 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-
 #include "sysdep.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <termios.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <pwd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <syslog.h>
 
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
-#include <sys/wait.h>
-#include <ctype.h>
+#include <stdio.h>
 #include <string.h>
-#include <limits.h>
+#include <syslog.h>
+#include <assert.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <assert.h>
 #if HAVE_BACKTRACE
 #include <execinfo.h>
 #endif
 
 #include <libcitadel.h>
-#include "citadel.h"
-#include "server.h"
-#include "citserver.h"
-#include "support.h"
-#include "config.h"
-#include "control.h"
-#include "user_ops.h"
-#include "database.h"
-#include "msgbase.h"
-#include "internet_addressing.h"
-#include "genstamp.h"
-#include "domain.h"
-#include "clientsocket.h"
-#include "locate_host.h"
-#include "citadel_dirs.h"
 
-#include "event_client.h"
 #include "ctdl_module.h"
-
+#include "event_client.h"
 
 ConstStr IOStates[] = {
        {HKEY("DB Queue")},
@@ -124,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;
@@ -132,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;
@@ -160,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;
 }
 
@@ -257,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;
@@ -265,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;
@@ -295,6 +264,25 @@ eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB)
        return eSendReply;
 }
 
+eNextState EventQueueDBOperation(AsyncIO *IO, IO_CallBack CB, int CloseFDs)
+{
+       StopClientWatchers(IO, CloseFDs);
+       IO->ReAttachCB = CB;
+       return eDBQuery;
+}
+eNextState DBQueueEventContext(AsyncIO *IO, IO_CallBack CB)
+{
+       StopDBWatchers(IO);
+       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);
 
 eNextState QueueCurlContext(AsyncIO *IO)
@@ -334,7 +322,14 @@ eNextState QueueCurlContext(AsyncIO *IO)
        return eSendReply;
 }
 
-void DestructCAres(AsyncIO *IO);
+eNextState CurlQueueDBOperation(AsyncIO *IO, IO_CallBack CB)
+{
+       StopCurlWatchers(IO);
+       IO->ReAttachCB = CB;
+       return eDBQuery;
+}
+
+
 void FreeAsyncIOContents(AsyncIO *IO)
 {
        CitContext *Ctx = IO->CitContext;
@@ -343,8 +338,6 @@ void FreeAsyncIOContents(AsyncIO *IO)
        FreeStrBuf(&IO->SendBuf.Buf);
        FreeStrBuf(&IO->RecvBuf.Buf);
 
-       DestructCAres(IO);
-
        FreeURL(&IO->ConnectMe);
        FreeStrBuf(&IO->HttpReq.ReplyData);
 
@@ -356,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);
@@ -376,6 +374,8 @@ void StopClientWatchers(AsyncIO *IO, int CloseFD)
 
 void StopCurlWatchers(AsyncIO *IO)
 {
+       EVM_syslog(LOG_DEBUG, "EVENT StopCurlWatchers \n");
+
        ev_timer_stop (event_base, &IO->rw_timeout);
        ev_timer_stop(event_base, &IO->conn_fail);
        ev_idle_stop(event_base, &IO->unwind_stack);
@@ -385,6 +385,9 @@ void StopCurlWatchers(AsyncIO *IO)
        ev_io_stop(event_base, &IO->send_event);
        ev_io_stop(event_base, &IO->recv_event);
 
+       curl_easy_cleanup(IO->HttpReq.chnd);
+       IO->HttpReq.chnd = NULL;
+
        if (IO->SendBuf.fd != 0) {
                close(IO->SendBuf.fd);
        }
@@ -506,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);
+                       }
                }
        }
 
@@ -1244,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: