From 4f299f8d09ee4de346920b9b2905fcb8d4dbdfc4 Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Tue, 20 Jan 2015 23:56:22 +0100 Subject: [PATCH] Use a Type for the stream pointers instead of void* so we have better error checking. --- citadel/techdoc/citadel_thread_io.txt | 4 +++- libcitadel/lib/libcitadel.h | 7 ++++--- libcitadel/lib/stringbuf.c | 16 ++++++++-------- webcit/tcp_sockets.c | 10 +++++----- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/citadel/techdoc/citadel_thread_io.txt b/citadel/techdoc/citadel_thread_io.txt index e74fdd2ae..bdcae91cf 100644 --- a/citadel/techdoc/citadel_thread_io.txt +++ b/citadel/techdoc/citadel_thread_io.txt @@ -65,7 +65,7 @@ The IO-Event-queue lives in this thread. Code running in this thread has to obey - other threads mustn't access memory belonging to an IO job - New IO contexts have to be registered via QueueEventContext() from other threads; Its callback are then called from whithin the event queue to start its logic. - New HTTP-IO contexts have to be registered via QueueCurlContext() - - once you've registered a context, you must not access its memory anymore to avoid race conditions + - once you've registered a context, you must not access its memory anymore to avoid race conditions. ==== Logic in event_client ==== InitIOStruct() which prepares an AsyncIO struct for later use before using QueueEventContext() to activate it. @@ -97,3 +97,5 @@ Usually a context should respect that there may be others around also wanting to While its ok to do _some_ requests in a row (like deleting some messages, updating messages, etc.), loops over unknown numbers of queries should be unrolled and be done one query at a time (i.e. looking up messages in the 'already known table') +=== Transitioning back & forth === +If the application logic has found that a transition is to be made from the event IO to the DB IO thread. Do so by calling DBQueueEventContext() (DB -> IO) EventQueueDBOperation() (IO->DB) and pass its return value up the row to enable the controll logic to do the actual transition for you. diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index 00e841018..3e48a35f3 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -346,9 +346,10 @@ typedef enum __eStreamType { eEmtyCodec } eStreamType; -void *StrBufNewStreamContext(eStreamType type, const char **Err); -int StrBufDestroyStreamContext(eStreamType type, void **Stream, const char **Err); -int StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, const char* pIn, long pInLen, void *Stream, int LastChunk, const char **Err); +typedef struct vStreamT vStreamT; +vStreamT *StrBufNewStreamContext(eStreamType type, const char **Err); +int StrBufDestroyStreamContext(eStreamType type, vStreamT **Stream, const char **Err); +int StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, const char* pIn, long pInLen, vStreamT *Stream, int LastChunk, const char **Err); int StrBufDecodeBase64(StrBuf *Buf); int StrBufDecodeBase64To(const StrBuf *BufIn, StrBuf *BufOut); diff --git a/libcitadel/lib/stringbuf.c b/libcitadel/lib/stringbuf.c index 813def36a..baa9c69a7 100644 --- a/libcitadel/lib/stringbuf.c +++ b/libcitadel/lib/stringbuf.c @@ -2859,7 +2859,7 @@ typedef struct __z_enc_stream { z_stream zstream; } z_enc_stream; -void *StrBufNewStreamContext(eStreamType type, const char **Err) +vStreamT *StrBufNewStreamContext(eStreamType type, const char **Err) { base64_decodestate *state;; *Err = NULL; @@ -2870,7 +2870,7 @@ void *StrBufNewStreamContext(eStreamType type, const char **Err) case eBase64Encode: state = (base64_decodestate*) malloc(sizeof(base64_decodestate)); base64_init_decodestate(state); - return state; + return (vStreamT*) state; break; case eZLibDecode: { @@ -2886,11 +2886,11 @@ void *StrBufNewStreamContext(eStreamType type, const char **Err) err = inflateInit(&stream->zstream); if (err != Z_OK) { - StrBufDestroyStreamContext(type, (void**)&stream, Err); + StrBufDestroyStreamContext(type, (vStreamT**) &stream, Err); *Err = zError(err); return NULL; } - return stream; + return (vStreamT*) stream; } case eZLibEncode: @@ -2918,11 +2918,11 @@ void *StrBufNewStreamContext(eStreamType type, const char **Err) DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); if (err != Z_OK) { - StrBufDestroyStreamContext(type, (void**) &stream, Err); + StrBufDestroyStreamContext(type, (vStreamT**) &stream, Err); *Err = zError(err); return NULL; } - return stream; + return (vStreamT*) stream; } case eEmtyCodec: /// TODO @@ -2932,7 +2932,7 @@ void *StrBufNewStreamContext(eStreamType type, const char **Err) return NULL; } -int StrBufDestroyStreamContext(eStreamType type, void **vStream, const char **Err) +int StrBufDestroyStreamContext(eStreamType type, vStreamT **vStream, const char **Err) { int err; int rc = 0; @@ -2975,7 +2975,7 @@ int StrBufDestroyStreamContext(eStreamType type, void **vStream, const char **Er return rc; } -int StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, const char* pIn, long pInLen, void *vStream, int LastChunk, const char **Err) +int StrBufStreamTranscode(eStreamType type, IOBuffer *Target, IOBuffer *In, const char* pIn, long pInLen, vStreamT *vStream, int LastChunk, const char **Err) { int rc = 0; switch (type) diff --git a/webcit/tcp_sockets.c b/webcit/tcp_sockets.c index 70e3cff8c..2f969242e 100644 --- a/webcit/tcp_sockets.c +++ b/webcit/tcp_sockets.c @@ -560,7 +560,7 @@ void serv_read_binary_to_http(StrBuf *MimeType, size_t total_len, int is_static, StrBuf *BufHeader = NULL; StrBuf *Buf; StrBuf *pBuf = NULL; - void *SC = NULL; + vStreamT *SC = NULL; IOBuffer ReadBuffer; IOBuffer WriteBuffer; @@ -641,7 +641,7 @@ void serv_read_binary_to_http(StrBuf *MimeType, size_t total_len, int is_static, FreeStrBuf(&Buf); FreeStrBuf(&WriteBuffer.Buf); FreeStrBuf(&BufHeader); - if (StrBufDestroyStreamContext(eZLibEncode, SC, &Err) && Err) { + if (StrBufDestroyStreamContext(eZLibEncode, &SC, &Err) && Err) { syslog(LOG_ERR, "Error while destroying stream context: %s", Err); } return; @@ -658,8 +658,8 @@ void serv_read_binary_to_http(StrBuf *MimeType, size_t total_len, int is_static, FreeStrBuf(&Buf); FreeStrBuf(&WriteBuffer.Buf); FreeStrBuf(&BufHeader); - StrBufDestroyStreamContext(eZLibEncode, SC, &Err); - if (StrBufDestroyStreamContext(eZLibEncode, SC, &Err) && Err) { + StrBufDestroyStreamContext(eZLibEncode, &SC, &Err); + if (StrBufDestroyStreamContext(eZLibEncode, &SC, &Err) && Err) { syslog(LOG_ERR, "Error while destroying stream context: %s", Err); } return; @@ -729,7 +729,7 @@ void serv_read_binary_to_http(StrBuf *MimeType, size_t total_len, int is_static, } } - if (SC && StrBufDestroyStreamContext(eZLibEncode, SC, &Err) && Err) { + if (SC && StrBufDestroyStreamContext(eZLibEncode, &SC, &Err) && Err) { syslog(LOG_ERR, "Error while destroying stream context: %s", Err); } FreeStrBuf(&WriteBuffer.Buf); -- 2.30.2