Back to index

citadel  8.12
Classes | Defines | Typedefs | Functions | Variables
serv_eventclient.c File Reference
#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>
#include <time.h>
#include <sys/wait.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <assert.h>
#include <arpa/inet.h>
#include <libcitadel.h>
#include <curl/curl.h>
#include <curl/multi.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "support.h"
#include "ctdl_module.h"
#include "event_client.h"
#include "serv_curl.h"

Go to the source code of this file.

Classes

struct  _evcurl_global_data

Defines

#define DBGLOG(LEVEL)   if ((LEVEL != LOG_DEBUG) || (DebugCurl != 0))
#define EVCURL_syslog(LEVEL, FORMAT,...)
#define EVCURLM_syslog(LEVEL, FORMAT)
#define CURL_syslog(LEVEL, FORMAT,...)   DBGLOG (LEVEL) syslog(LEVEL, "CURL: " FORMAT, __VA_ARGS__)
#define CURLM_syslog(LEVEL, FORMAT)   DBGLOG (LEVEL) syslog(LEVEL, "CURL: " FORMAT)
#define MOPT(s, v)

Typedefs

typedef struct _evcurl_global_data evcurl_global_data

Functions

static void gotstatus (int nnrun)
static void stepmulti (void *data, curl_socket_t fd, int which)
static void gottime (struct ev_loop *loop, ev_timer *timeev, int events)
static void got_in (struct ev_loop *loop, ev_io *ioev, int events)
static void got_out (struct ev_loop *loop, ev_io *ioev, int events)
static size_t gotdata (void *data, size_t size, size_t nmemb, void *cglobal)
static int gotwatchtime (CURLM *multi, long tblock_ms, void *cglobal)
static int gotwatchsock (CURL *easy, curl_socket_t fd, int action, void *cglobal, void *vIO)
void curl_init_connectionpool (void)
int evcurl_init (AsyncIO *IO)
static void IOcurl_abort_shutdown_callback (struct ev_loop *loop, ev_cleanup *watcher, int revents)
eNextState evcurl_handle_start (AsyncIO *IO)
static void WakeupCurlCallback (EV_P_ ev_async *w, int revents)
static void evcurl_shutdown (void)
static void QueueEventAddCallback (EV_P_ ev_async *w, int revents)
static void EventExitCallback (EV_P_ ev_async *w, int revents)
void InitEventQueue (void)
void CtdlDestroyEVCleanupHooks (void)
void * client_event_thread (void *arg)
void ShutDownDBCLient (AsyncIO *IO)
static void DBQueueEventAddCallback (EV_P_ ev_async *w, int revents)
static void DBEventExitCallback (EV_P_ ev_async *w, int revents)
void DBInitEventQueue (void)
void * db_event_thread (void *arg)
void ShutDownEventQueues (void)
void DebugEventloopEnable (const int n)
void DebugEventloopBacktraceEnable (const int n)
void DebugCurlEnable (const int n)
 CTDL_MODULE_INIT (event_client)

Variables

ev_loop * event_base
int DebugEventLoop = 0
int DebugEventLoopBacktrace = 0
int DebugCurl = 0
long EvIDSource = 1
ev_async WakeupCurl
evcurl_global_data global
int evbase_count = 0
pthread_mutex_t EventQueueMutex
pthread_mutex_t EventExitQueueMutex
HashList * QueueEvents = NULL
HashList * InboundEventQueue = NULL
HashList * InboundEventQueues [2] = { NULL, NULL }
ev_async AddJob
ev_async ExitEventLoop
int EVQShutDown
ev_loop * event_db
int evdb_count = 0
pthread_mutex_t DBEventQueueMutex
pthread_mutex_t DBEventExitQueueMutex
HashList * DBQueueEvents = NULL
HashList * DBInboundEventQueue = NULL
HashList * DBInboundEventQueues [2] = { NULL, NULL }
ev_async DBAddJob
ev_async DBExitEventLoop

Class Documentation

struct _evcurl_global_data

Definition at line 99 of file serv_eventclient.c.

Class Members
int magic
CURLM * mhnd
int nrun
ev_timer timeev

Define Documentation

#define CURL_syslog (   LEVEL,
  FORMAT,
  ... 
)    DBGLOG (LEVEL) syslog(LEVEL, "CURL: " FORMAT, __VA_ARGS__)

Definition at line 81 of file serv_eventclient.c.

#define CURLM_syslog (   LEVEL,
  FORMAT 
)    DBGLOG (LEVEL) syslog(LEVEL, "CURL: " FORMAT)

Definition at line 84 of file serv_eventclient.c.

#define DBGLOG (   LEVEL)    if ((LEVEL != LOG_DEBUG) || (DebugCurl != 0))

Definition at line 71 of file serv_eventclient.c.

#define EVCURL_syslog (   LEVEL,
  FORMAT,
  ... 
)
Value:
DBGLOG (LEVEL) syslog(LEVEL, "EVCURL:IO[%ld]CC[%d] " FORMAT,   \
                           IO->ID, CCID, __VA_ARGS__)

Definition at line 73 of file serv_eventclient.c.

#define EVCURLM_syslog (   LEVEL,
  FORMAT 
)
Value:
DBGLOG (LEVEL) syslog(LEVEL, "EVCURL:IO[%ld]CC[%d] " FORMAT,   \
                           IO->ID, CCID)

Definition at line 77 of file serv_eventclient.c.

#define MOPT (   s,
 
)
Value:
do {                                                    \
              sta = curl_multi_setopt(mhnd, (CURLMOPT_##s), (v));     \
              if (sta) {                                       \
                     EVQ_syslog(LOG_ERR, "error setting option "      \
                            #s " on curl multi handle: %s\n",  \
                            curl_easy_strerror(sta));          \
                     exit (1);                                 \
              }                                                \
       } while (0)

Definition at line 87 of file serv_eventclient.c.


Typedef Documentation


Function Documentation

void* client_event_thread ( void *  arg)

what todo here? CtdlClearSystemContext();

Definition at line 670 of file serv_eventclient.c.

{
       struct CitContext libev_client_CC;

       CtdlFillSystemContext(&libev_client_CC, "LibEv Thread");
//     citthread_setspecific(MyConKey, (void *)&smtp_queue_CC);
       EVQM_syslog(LOG_DEBUG, "client_event_thread() initializing\n");

       event_base = ev_default_loop (EVFLAG_AUTO);
       ev_async_init(&AddJob, QueueEventAddCallback);
       ev_async_start(event_base, &AddJob);
       ev_async_init(&ExitEventLoop, EventExitCallback);
       ev_async_start(event_base, &ExitEventLoop);
       ev_async_init(&WakeupCurl, WakeupCurlCallback);
       ev_async_start(event_base, &WakeupCurl);

       curl_init_connectionpool();

       ev_run (event_base, 0);

       EVQM_syslog(LOG_DEBUG, "client_event_thread() exiting\n");

       pthread_mutex_lock(&EventExitQueueMutex);
       ev_loop_destroy (EV_DEFAULT_UC);
       event_base = NULL;
       DeleteHash(&QueueEvents);
       InboundEventQueue = NULL;
       DeleteHash(&InboundEventQueues[0]);
       DeleteHash(&InboundEventQueues[1]);
/*     citthread_mutex_destroy(&EventQueueMutex); TODO */
       evcurl_shutdown();

       CtdlDestroyEVCleanupHooks();

       pthread_mutex_unlock(&EventExitQueueMutex);
       EVQShutDown = 1;
       return(NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CTDL_MODULE_INIT ( event_client  )

Definition at line 865 of file serv_eventclient.c.

Here is the call graph for this function:

void CtdlDestroyEVCleanupHooks ( void  )

Definition at line 583 of file serv_extensions.c.

{
       CleanupFunctionHook *cur, *p;

       cur = EVCleanupHookTable;
       while (cur != NULL)
       {
              MODM_syslog(LOG_DEBUG, "Destroyed cleanup function\n");
              p = cur->next;
              free(cur);
              cur = p;
       }
       EVCleanupHookTable = NULL;
}

Here is the caller graph for this function:

void curl_init_connectionpool ( void  )

Definition at line 398 of file serv_eventclient.c.

{
       CURLM *mhnd ;

       ev_timer_init(&global.timeev, &gottime, 14.0, 14.0);
       global.timeev.data = (void *)&global;
       global.nrun = -1;
       CURLcode sta = curl_global_init(CURL_GLOBAL_ALL);

       if (sta)
       {
              CURL_syslog(LOG_ERR,
                         "error initializing curl library: %s\n",
                         curl_easy_strerror(sta));

              exit(1);
       }
       mhnd = global.mhnd = curl_multi_init();
       if (!mhnd)
       {
              CURLM_syslog(LOG_ERR,
                          "error initializing curl multi handle\n");
              exit(3);
       }

       MOPT(SOCKETFUNCTION, &gotwatchsock);
       MOPT(SOCKETDATA, (void *)&global);
       MOPT(TIMERFUNCTION, &gotwatchtime);
       MOPT(TIMERDATA, (void *)&global);

       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* db_event_thread ( void *  arg)

Definition at line 803 of file serv_eventclient.c.

{
       ev_loop *tmp;
       struct CitContext libev_msg_CC;

       CtdlFillSystemContext(&libev_msg_CC, "LibEv DB IO Thread");

       EVQM_syslog(LOG_DEBUG, "dbevent_thread() initializing\n");

       tmp = event_db = ev_loop_new (EVFLAG_AUTO);

       ev_async_init(&DBAddJob, DBQueueEventAddCallback);
       ev_async_start(event_db, &DBAddJob);
       ev_async_init(&DBExitEventLoop, DBEventExitCallback);
       ev_async_start(event_db, &DBExitEventLoop);

       ev_run (event_db, 0);

       pthread_mutex_lock(&DBEventExitQueueMutex);

       event_db = NULL;
       EVQM_syslog(LOG_INFO, "dbevent_thread() exiting\n");

       DeleteHash(&DBQueueEvents);
       DBInboundEventQueue = NULL;
       DeleteHash(&DBInboundEventQueues[0]);
       DeleteHash(&DBInboundEventQueues[1]);

/*     citthread_mutex_destroy(&DBEventQueueMutex); TODO */

       ev_loop_destroy (tmp);
       pthread_mutex_unlock(&DBEventExitQueueMutex);
       return(NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void DBEventExitCallback ( EV_P_ ev_async *  w,
int  revents 
) [static]

Definition at line 781 of file serv_eventclient.c.

{
       EVQM_syslog(LOG_DEBUG, "DB EVENT Q exiting.\n");
       ev_break(event_db, EVBREAK_ALL);
}

Here is the caller graph for this function:

void DBInitEventQueue ( void  )

Definition at line 789 of file serv_eventclient.c.

{
       pthread_mutex_init(&DBEventQueueMutex, NULL);
       pthread_mutex_init(&DBEventExitQueueMutex, NULL);

       DBQueueEvents = NewHash(1, Flathash);
       DBInboundEventQueues[0] = NewHash(1, Flathash);
       DBInboundEventQueues[1] = NewHash(1, Flathash);
       DBInboundEventQueue = DBInboundEventQueues[0];
}

Here is the caller graph for this function:

static void DBQueueEventAddCallback ( EV_P_ ev_async *  w,
int  revents 
) [static]

Definition at line 728 of file serv_eventclient.c.

{
       CitContext *Ctx;
       ev_tstamp Now;
       HashList *q;
       void *v;
       HashPos *It;
       long len;
       const char *Key;

       /* get the control command... */
       pthread_mutex_lock(&DBEventQueueMutex);

       if (DBInboundEventQueues[0] == DBInboundEventQueue) {
              DBInboundEventQueue = DBInboundEventQueues[1];
              q = DBInboundEventQueues[0];
       }
       else {
              DBInboundEventQueue = DBInboundEventQueues[0];
              q = DBInboundEventQueues[1];
       }
       pthread_mutex_unlock(&DBEventQueueMutex);

       Now = ev_now (event_db);
       It = GetNewHashPos(q, 0);
       while (GetNextHashPos(q, It, &len, &Key, &v))
       {
              IOAddHandler *h = v;
              eNextState rc;
              if (h->IO->ID == 0)
                     h->IO->ID = EvIDSource++;
              if (h->IO->StartDB == 0.0)
                     h->IO->StartDB = Now;
              h->IO->Now = Now;

              Ctx = h->IO->CitContext;
              become_session(Ctx);
              ev_cleanup_start(event_db, &h->IO->db_abort_by_shutdown);
              rc = h->EvAttch(h->IO);
              switch (rc)
              {
              case eAbort:
                     ShutDownDBCLient(h->IO);
              default:
                     break;
              }
       }
       DeleteHashPos(&It);
       DeleteHashContent(&q);
       EVQM_syslog(LOG_DEBUG, "DBEVENT Q Add done.\n");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void DebugCurlEnable ( const int  n)

Definition at line 860 of file serv_eventclient.c.

{
       DebugCurl = n;
}

Here is the caller graph for this function:

void DebugEventloopBacktraceEnable ( const int  n)

Definition at line 855 of file serv_eventclient.c.

Here is the caller graph for this function:

void DebugEventloopEnable ( const int  n)

Definition at line 851 of file serv_eventclient.c.

Here is the caller graph for this function:

Definition at line 520 of file serv_eventclient.c.

{
       CURLMcode msta;
       CURLcode sta;
       CURL *chnd;

       chnd = IO->HttpReq.chnd;
       EVCURL_syslog(LOG_DEBUG,
                "EVCURL: Loading URL: %s\n", IO->ConnectMe->PlainUrl);
       OPT(URL, IO->ConnectMe->PlainUrl);
       if (StrLength(IO->ConnectMe->CurlCreds))
       {
              OPT(HTTPAUTH, (long)CURLAUTH_BASIC);
              OPT(USERPWD, ChrPtr(IO->ConnectMe->CurlCreds));
       }
       if (StrLength(IO->HttpReq.PostData) > 0)
       {
              OPT(POSTFIELDS, ChrPtr(IO->HttpReq.PostData));
              OPT(POSTFIELDSIZE, StrLength(IO->HttpReq.PostData));

       }
       else if ((IO->HttpReq.PlainPostDataLen != 0) &&
               (IO->HttpReq.PlainPostData != NULL))
       {
              OPT(POSTFIELDS, IO->HttpReq.PlainPostData);
              OPT(POSTFIELDSIZE, IO->HttpReq.PlainPostDataLen);
       }
       OPT(HTTPHEADER, IO->HttpReq.headers);

       IO->NextState = eConnect;
       EVCURLM_syslog(LOG_DEBUG, "EVCURL: attaching to curl multi handle\n");
       msta = curl_multi_add_handle(global.mhnd, IO->HttpReq.chnd);
       if (msta)
       {
              EVCURL_syslog(LOG_ERR,
                       "EVCURL: error attaching to curl multi handle: %s\n",
                       curl_multi_strerror(msta));
       }

       IO->HttpReq.attached = 1;
       ev_async_send (event_base, &WakeupCurl);

       ev_cleanup_init(&IO->abort_by_shutdown,
                     IOcurl_abort_shutdown_callback);

       ev_cleanup_start(event_base, &IO->abort_by_shutdown);

       return eReadMessage;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int evcurl_init ( AsyncIO IO)

Definition at line 431 of file serv_eventclient.c.

{
       CURLcode sta;
       CURL *chnd;

       EVCURLM_syslog(LOG_DEBUG, "EVCURL: evcurl_init called ms\n");
       IO->HttpReq.attached = 0;
       chnd = IO->HttpReq.chnd = curl_easy_init();
       if (!chnd)
       {
              EVCURLM_syslog(LOG_ERR, "EVCURL: error initializing curl handle\n");
              return 0;
       }

#if DEBUG
       OPT(VERBOSE, (long)1);
#endif
       OPT(NOPROGRESS, 1L);

       OPT(NOSIGNAL, 1L);
       OPT(FAILONERROR, (long)1);
       OPT(ENCODING, "");
       OPT(FOLLOWLOCATION, (long)0);
       OPT(MAXREDIRS, (long)0);
       OPT(USERAGENT, CITADEL);

       OPT(TIMEOUT, (long)1800);
       OPT(LOW_SPEED_LIMIT, (long)64);
       OPT(LOW_SPEED_TIME, (long)600);
       OPT(CONNECTTIMEOUT, (long)600);
       OPT(PRIVATE, (void *)IO);

       OPT(FORBID_REUSE, 1);
       OPT(WRITEFUNCTION, &gotdata);
       OPT(WRITEDATA, (void *)IO);
       OPT(ERRORBUFFER, IO->HttpReq.errdesc);

       if ((!IsEmptyStr(config.c_ip_addr))
              && (strcmp(config.c_ip_addr, "*"))
              && (strcmp(config.c_ip_addr, "::"))
              && (strcmp(config.c_ip_addr, "0.0.0.0"))
              )
       {
              OPT(INTERFACE, config.c_ip_addr);
       }

#ifdef CURLOPT_HTTP_CONTENT_DECODING
       OPT(HTTP_CONTENT_DECODING, 1);
       OPT(ENCODING, "");
#endif

       IO->HttpReq.headers = curl_slist_append(IO->HttpReq.headers,
                                          "Connection: close");

       return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void evcurl_shutdown ( void  ) [static]

Definition at line 577 of file serv_eventclient.c.

{
       curl_global_cleanup();
       curl_multi_cleanup(global.mhnd);
       CURLM_syslog(LOG_DEBUG, "exiting\n");
}

Here is the caller graph for this function:

static void EventExitCallback ( EV_P_ ev_async *  w,
int  revents 
) [static]

Definition at line 645 of file serv_eventclient.c.

{
       ev_break(event_base, EVBREAK_ALL);

       EVQM_syslog(LOG_DEBUG, "EVENT Q exiting.\n");
}

Here is the caller graph for this function:

static void got_in ( struct ev_loop *  loop,
ev_io *  ioev,
int  events 
) [static]

Definition at line 255 of file serv_eventclient.c.

{
       CURL_syslog(LOG_DEBUG,
                  "EVCURL: waking up curl for io on fd %d\n",
                  (int)ioev->fd);

       stepmulti(ioev->data, ioev->fd, CURL_CSELECT_IN);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void got_out ( struct ev_loop *  loop,
ev_io *  ioev,
int  events 
) [static]

Definition at line 265 of file serv_eventclient.c.

{
       CURL_syslog(LOG_DEBUG,
                  "waking up curl for io on fd %d\n",
                  (int)ioev->fd);

       stepmulti(ioev->data, ioev->fd, CURL_CSELECT_OUT);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static size_t gotdata ( void *  data,
size_t  size,
size_t  nmemb,
void *  cglobal 
) [static]

Definition at line 275 of file serv_eventclient.c.

                                                              {
       AsyncIO *IO = (AsyncIO*) cglobal;

       if (IO->HttpReq.ReplyData == NULL)
       {
              IO->HttpReq.ReplyData = NewStrBufPlain(NULL, SIZ);
       }
       IO->Now = ev_now(event_base);
       return CurlFillStrBuf_callback(data,
                                   size,
                                   nmemb,
                                   IO->HttpReq.ReplyData);
}

Here is the caller graph for this function:

static void gotstatus ( int  nnrun) [static]

Definition at line 110 of file serv_eventclient.c.

{
       CURLMsg *msg;
       int nmsg;

       global.nrun = nnrun;

       CURLM_syslog(LOG_DEBUG,
                   "gotstatus(): about to call curl_multi_info_read\n");
       while ((msg = curl_multi_info_read(global.mhnd, &nmsg))) {
              CURL_syslog(LOG_DEBUG,
                         "got curl multi_info message msg=%d\n",
                         msg->msg);

              if (CURLMSG_DONE == msg->msg) {
                     CURL *chnd;
                     char *chandle = NULL;
                     CURLcode sta;
                     CURLMcode msta;
                     AsyncIO*IO;

                     chandle = NULL;;
                     chnd = msg->easy_handle;
                     sta = curl_easy_getinfo(chnd,
                                          CURLINFO_PRIVATE,
                                          &chandle);
                     if (sta) {
                            syslog(LOG_ERR,
                                   "error asking curl for private"
                                   " cookie of curl handle: %s\n",
                                   curl_easy_strerror(sta));
                            continue;
                     }
                     IO = (AsyncIO *)chandle;
                     if (IO->ID == 0) {
                            EVCURL_syslog(LOG_ERR,
                                         "Error, invalid IO context %p\n",
                                         IO);
                            continue;
                     }

                     EVCURLM_syslog(LOG_DEBUG, "request complete\n");

                     IO->Now = ev_now(event_base);

                     ev_io_stop(event_base, &IO->recv_event);
                     ev_io_stop(event_base, &IO->send_event);

                     sta = msg->data.result;
                     if (sta) {
                            EVCURL_syslog(LOG_ERR,
                                         "error description: %s\n",
                                         IO->HttpReq.errdesc);
                            EVCURL_syslog(LOG_ERR,
                                         "error performing request: %s\n",
                                         curl_easy_strerror(sta));
                     }
                     sta = curl_easy_getinfo(chnd,
                                          CURLINFO_RESPONSE_CODE,
                                          &IO->HttpReq.httpcode);
                     if (sta)
                            EVCURL_syslog(LOG_ERR,
                                         "error asking curl for "
                                         "response code from request: %s\n",
                                         curl_easy_strerror(sta));
                     EVCURL_syslog(LOG_DEBUG,
                                  "http response code was %ld\n",
                                  (long)IO->HttpReq.httpcode);


                     curl_slist_free_all(IO->HttpReq.headers);
                     msta = curl_multi_remove_handle(global.mhnd, chnd);
                     if (msta)
                            EVCURL_syslog(LOG_ERR,
                                         "warning problem detaching "
                                         "completed handle from curl multi: "
                                         "%s\n",
                                         curl_multi_strerror(msta));

                     ev_cleanup_stop(event_base, &IO->abort_by_shutdown);

                     IO->HttpReq.attached = 0;
                     switch(IO->SendDone(IO))
                     {
                     case eDBQuery:
                            curl_easy_cleanup(IO->HttpReq.chnd);
                            IO->HttpReq.chnd = NULL;
                            break;
                     case eSendDNSQuery:
                     case eReadDNSReply:
                     case eConnect:
                     case eSendReply:
                     case eSendMore:
                     case eSendFile:
                     case eReadMessage:
                     case eReadMore:
                     case eReadPayload:
                     case eReadFile:
                            curl_easy_cleanup(IO->HttpReq.chnd);
                            IO->HttpReq.chnd = NULL;
                            break;
                     case eTerminateConnection:
                     case eAbort:
                            curl_easy_cleanup(IO->HttpReq.chnd);
                            IO->HttpReq.chnd = NULL;
                            FreeStrBuf(&IO->HttpReq.ReplyData);
                            FreeURL(&IO->ConnectMe);
                            RemoveContext(IO->CitContext);
                            IO->Terminate(IO);
                     }
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void gottime ( struct ev_loop *  loop,
ev_timer *  timeev,
int  events 
) [static]

Definition at line 248 of file serv_eventclient.c.

{
       CURLM_syslog(LOG_DEBUG, "EVCURL: waking up curl for timeout\n");
       stepmulti(NULL, CURL_SOCKET_TIMEOUT, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int gotwatchsock ( CURL *  easy,
curl_socket_t  fd,
int  action,
void *  cglobal,
void *  vIO 
) [static]

Definition at line 303 of file serv_eventclient.c.

{
       evcurl_global_data *global = cglobal;
       CURLM *mhnd = global->mhnd;
       char *f;
       AsyncIO *IO = (AsyncIO*) vIO;
       CURLcode sta;
       const char *Action;

       if (IO == NULL) {
              sta = curl_easy_getinfo(easy, CURLINFO_PRIVATE, &f);
              if (sta) {
                     CURL_syslog(LOG_ERR,
                                "EVCURL: error asking curl for private "
                                "cookie of curl handle: %s\n",
                                curl_easy_strerror(sta));
                     return -1;
              }
              IO = (AsyncIO *) f;
              EVCURL_syslog(LOG_DEBUG,
                           "EVCURL: got socket for URL: %s\n",
                           IO->ConnectMe->PlainUrl);

              if (IO->SendBuf.fd != 0)
              {
                     ev_io_stop(event_base, &IO->recv_event);
                     ev_io_stop(event_base, &IO->send_event);
              }
              IO->SendBuf.fd = fd;
              ev_io_init(&IO->recv_event, &got_in, fd, EV_READ);
              ev_io_init(&IO->send_event, &got_out, fd, EV_WRITE);
              curl_multi_assign(mhnd, fd, IO);
       }

       IO->Now = ev_now(event_base);

       Action = "";
       switch (action)
       {
       case CURL_POLL_NONE:
              Action = "CURL_POLL_NONE";
              break;
       case CURL_POLL_REMOVE:
              Action = "CURL_POLL_REMOVE";
              break;
       case CURL_POLL_IN:
              Action = "CURL_POLL_IN";
              break;
       case CURL_POLL_OUT:
              Action = "CURL_POLL_OUT";
              break;
       case CURL_POLL_INOUT:
              Action = "CURL_POLL_INOUT";
              break;
       }


       EVCURL_syslog(LOG_DEBUG,
                    "EVCURL: gotwatchsock called fd=%d action=%s[%d]\n",
                    (int)fd, Action, action);

       switch (action)
       {
       case CURL_POLL_NONE:
              EVCURLM_syslog(LOG_DEBUG,
                            "called first time "
                            "to register this sockwatcker\n");
              break;
       case CURL_POLL_REMOVE:
              EVCURLM_syslog(LOG_DEBUG,
                            "called last time to unregister "
                            "this sockwatcher\n");
              ev_io_stop(event_base, &IO->recv_event);
              ev_io_stop(event_base, &IO->send_event);
              break;
       case CURL_POLL_IN:
              ev_io_start(event_base, &IO->recv_event);
              ev_io_stop(event_base, &IO->send_event);
              break;
       case CURL_POLL_OUT:
              ev_io_start(event_base, &IO->send_event);
              ev_io_stop(event_base, &IO->recv_event);
              break;
       case CURL_POLL_INOUT:
              ev_io_start(event_base, &IO->send_event);
              ev_io_start(event_base, &IO->recv_event);
              break;
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int gotwatchtime ( CURLM *  multi,
long  tblock_ms,
void *  cglobal 
) [static]

Definition at line 290 of file serv_eventclient.c.

                                                          {
       CURL_syslog(LOG_DEBUG, "EVCURL: gotwatchtime called %ld ms\n", tblock_ms);
       evcurl_global_data *global = cglobal;
       ev_timer_stop(EV_DEFAULT, &global->timeev);
       if (tblock_ms < 0 || 14000 < tblock_ms)
              tblock_ms = 14000;
       ev_timer_set(&global->timeev, 0.5e-3 + 1.0e-3 * tblock_ms, 14.0);
       ev_timer_start(EV_DEFAULT_UC, &global->timeev);
       curl_multi_perform(global, &global->nrun);
       return 0;
}

Here is the caller graph for this function:

void InitEventQueue ( void  )

Definition at line 654 of file serv_eventclient.c.

{
       pthread_mutex_init(&EventQueueMutex, NULL);
       pthread_mutex_init(&EventExitQueueMutex, NULL);

       QueueEvents = NewHash(1, Flathash);
       InboundEventQueues[0] = NewHash(1, Flathash);
       InboundEventQueues[1] = NewHash(1, Flathash);
       InboundEventQueue = InboundEventQueues[0];
}

Here is the caller graph for this function:

static void IOcurl_abort_shutdown_callback ( struct ev_loop *  loop,
ev_cleanup *  watcher,
int  revents 
) [static]

Definition at line 489 of file serv_eventclient.c.

{
       CURLMcode msta;
       AsyncIO *IO = watcher->data;

       if (IO == NULL)
              return;
       IO->Now = ev_now(event_base);
       EVCURL_syslog(LOG_DEBUG, "EVENT Curl: %s\n", __FUNCTION__);

       curl_slist_free_all(IO->HttpReq.headers);
       msta = curl_multi_remove_handle(global.mhnd, IO->HttpReq.chnd);
       if (msta)
       {
              EVCURL_syslog(LOG_ERR,
                           "EVCURL: warning problem detaching completed handle "
                           "from curl multi: %s\n",
                           curl_multi_strerror(msta));
       }

       curl_easy_cleanup(IO->HttpReq.chnd);
       IO->HttpReq.chnd = NULL;
       ev_cleanup_stop(event_base, &IO->abort_by_shutdown);
       ev_io_stop(event_base, &IO->recv_event);
       ev_io_stop(event_base, &IO->send_event);
       assert(IO->ShutdownAbort);
       IO->ShutdownAbort(IO);
}

Here is the caller graph for this function:

static void QueueEventAddCallback ( EV_P_ ev_async *  w,
int  revents 
) [static]

Definition at line 600 of file serv_eventclient.c.

{
       CitContext *Ctx;
       ev_tstamp Now;
       HashList *q;
       void *v;
       HashPos*It;
       long len;
       const char *Key;

       /* get the control command... */
       pthread_mutex_lock(&EventQueueMutex);

       if (InboundEventQueues[0] == InboundEventQueue) {
              InboundEventQueue = InboundEventQueues[1];
              q = InboundEventQueues[0];
       }
       else {
              InboundEventQueue = InboundEventQueues[0];
              q = InboundEventQueues[1];
       }
       pthread_mutex_unlock(&EventQueueMutex);
       Now = ev_now (event_base);
       It = GetNewHashPos(q, 0);
       while (GetNextHashPos(q, It, &len, &Key, &v))
       {
              IOAddHandler *h = v;
              if (h->IO->ID == 0) {
                     h->IO->ID = EvIDSource++;
              }
              if (h->IO->StartIO == 0.0)
                     h->IO->StartIO = Now;

              Ctx = h->IO->CitContext;
              become_session(Ctx);

              h->IO->Now = Now;
              h->EvAttch(h->IO);
       }
       DeleteHashPos(&It);
       DeleteHashContent(&q);
       EVQM_syslog(LOG_DEBUG, "EVENT Q Add done.\n");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ShutDownDBCLient ( AsyncIO IO)

Definition at line 136 of file event_client.c.

{
       CitContext *Ctx =IO->CitContext;
       become_session(Ctx);

       EVM_syslog(LOG_DEBUG, "DBEVENT Terminating.\n");
       StopDBWatchers(IO);

       assert(IO->DBTerminate);
       IO->DBTerminate(IO);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ShutDownEventQueues ( void  )

Definition at line 838 of file serv_eventclient.c.

{
       EVQM_syslog(LOG_DEBUG, "EVENT Qs triggering exits.\n");

       pthread_mutex_lock(&DBEventQueueMutex);
       ev_async_send (event_db, &DBExitEventLoop);
       pthread_mutex_unlock(&DBEventQueueMutex);

       pthread_mutex_lock(&EventQueueMutex);
       ev_async_send (EV_DEFAULT_ &ExitEventLoop);
       pthread_mutex_unlock(&EventQueueMutex);
}

Here is the caller graph for this function:

static void stepmulti ( void *  data,
curl_socket_t  fd,
int  which 
) [static]

Definition at line 225 of file serv_eventclient.c.

{
       int running_handles = 0;
       CURLMcode msta;

       msta = curl_multi_socket_action(global.mhnd,
                                   fd,
                                   which,
                                   &running_handles);

       CURLM_syslog(LOG_DEBUG, "stepmulti(): calling gotstatus()\n");
       if (msta)
              CURL_syslog(LOG_ERR,
                         "error in curl processing events"
                         "on multi handle, fd %d: %s\n",
                         (int)fd,
                         curl_multi_strerror(msta));

       if (global.nrun != running_handles)
              gotstatus(running_handles);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void WakeupCurlCallback ( EV_P_ ev_async *  w,
int  revents 
) [static]

Definition at line 570 of file serv_eventclient.c.

{
       CURLM_syslog(LOG_DEBUG, "waking up curl multi handle\n");

       curl_multi_perform(&global, CURL_POLL_NONE);
}

Here is the caller graph for this function:


Variable Documentation

ev_async AddJob

Definition at line 597 of file serv_eventclient.c.

ev_async DBAddJob

Definition at line 723 of file serv_eventclient.c.

pthread_mutex_t DBEventExitQueueMutex

Definition at line 718 of file serv_eventclient.c.

pthread_mutex_t DBEventQueueMutex

Definition at line 717 of file serv_eventclient.c.

ev_async DBExitEventLoop

Definition at line 724 of file serv_eventclient.c.

HashList* DBInboundEventQueue = NULL

Definition at line 720 of file serv_eventclient.c.

HashList* DBInboundEventQueues[2] = { NULL, NULL }

Definition at line 721 of file serv_eventclient.c.

HashList* DBQueueEvents = NULL

Definition at line 719 of file serv_eventclient.c.

int DebugCurl = 0

Definition at line 65 of file serv_eventclient.c.

int DebugEventLoop = 0

Definition at line 63 of file serv_eventclient.c.

Definition at line 64 of file serv_eventclient.c.

int evbase_count = 0

Definition at line 590 of file serv_eventclient.c.

int evdb_count = 0

Definition at line 716 of file serv_eventclient.c.

ev_loop* event_base

Definition at line 62 of file serv_eventclient.c.

ev_loop* event_db

Definition at line 715 of file serv_eventclient.c.

pthread_mutex_t EventExitQueueMutex

Definition at line 592 of file serv_eventclient.c.

pthread_mutex_t EventQueueMutex

Definition at line 591 of file serv_eventclient.c.

long EvIDSource = 1

Definition at line 67 of file serv_eventclient.c.

Definition at line 189 of file threads.c.

ev_async ExitEventLoop

Definition at line 598 of file serv_eventclient.c.

Definition at line 107 of file serv_eventclient.c.

HashList* InboundEventQueue = NULL

Definition at line 594 of file serv_eventclient.c.

HashList* InboundEventQueues[2] = { NULL, NULL }

Definition at line 595 of file serv_eventclient.c.

HashList* QueueEvents = NULL

Definition at line 593 of file serv_eventclient.c.

ev_async WakeupCurl

Definition at line 106 of file serv_eventclient.c.