Fixed IMAP IDLE on COMPRESSed streams

pull/2/merge
Hoa V. DINH 2014-03-13 21:21:35 -07:00
parent b6f16696b3
commit da8d464a02
10 changed files with 142 additions and 25 deletions

View File

@ -44,6 +44,7 @@
#include "mailstream.h"
#include "maillock.h"
#include "mailstream_cfstream.h"
#include "mailstream_compress.h"
#include "mailstream_cancel.h"
#include <string.h>
#include <stdlib.h>
@ -354,14 +355,14 @@ int mailstream_wait_idle(mailstream * s, int max_idle_delay)
int mailstream_setup_idle(mailstream * s)
{
int r;
if (s->idling) {
return -1;
}
if (s->low->driver == mailstream_cfstream_driver) {
mailstream_cfstream_setup_idle(s);
}
else {
r = mailstream_low_setup_idle(s->low);
if (r < 0) {
s->idle = mailstream_cancel_new();
if (s->idle == NULL)
return -1;
@ -374,28 +375,28 @@ int mailstream_setup_idle(mailstream * s)
void mailstream_interrupt_idle(mailstream * s)
{
int r;
if (!s->idling) {
return;
}
if (s->low->driver == mailstream_cfstream_driver) {
mailstream_cfstream_interrupt_idle(s);
}
else {
r = mailstream_low_interrupt_idle(s->low);
if (r < 0) {
mailstream_cancel_notify(s->idle);
}
}
void mailstream_unsetup_idle(mailstream * s)
{
int r;
if (!s->idling) {
return;
}
if (s->low->driver == mailstream_cfstream_driver) {
mailstream_cfstream_unsetup_idle(s);
}
else {
r = mailstream_low_unsetup_idle(s->low);
if (r < 0) {
mailstream_cancel_free(s->idle);
s->idle = NULL;
}

View File

@ -132,6 +132,10 @@ static int mailstream_low_cfstream_get_fd(mailstream_low * s);
static void mailstream_low_cfstream_cancel(mailstream_low * s);
static carray * mailstream_low_cfstream_get_certificate_chain(mailstream_low * s);
static int mailstream_low_cfstream_setup_idle(mailstream_low * s);
static int mailstream_low_cfstream_unsetup_idle(mailstream_low * s);
static int mailstream_low_cfstream_interrupt_idle(mailstream_low * s);
static mailstream_low_driver local_mailstream_cfstream_driver = {
/* mailstream_read */ mailstream_low_cfstream_read,
/* mailstream_write */ mailstream_low_cfstream_write,
@ -141,6 +145,9 @@ static mailstream_low_driver local_mailstream_cfstream_driver = {
/* mailstream_cancel */ mailstream_low_cfstream_cancel,
/* mailstream_get_cancel */ NULL,
/* mailstream_get_certificate_chain */ mailstream_low_cfstream_get_certificate_chain,
/* mailstream_setup_idle */ mailstream_low_cfstream_setup_idle,
/* mailstream_unsetup_idle */ mailstream_low_cfstream_unsetup_idle,
/* mailstream_interrupt_idle */ mailstream_low_cfstream_interrupt_idle,
};
mailstream_low_driver * mailstream_cfstream_driver =
@ -1073,48 +1080,53 @@ int mailstream_low_cfstream_wait_idle(mailstream_low * low, int max_idle_delay)
static void idleInterruptedPerform(void *info)
{
struct mailstream_cfstream_data * cfstream_data;
mailstream * s;
mailstream_low * s;
s = info;
//fprintf(stderr, "interrupt idle\n");
cfstream_data = (struct mailstream_cfstream_data *) s->low->data;
cfstream_data = (struct mailstream_cfstream_data *) s->data;
cfstream_data->idleInterrupted = true;
}
#endif
void mailstream_cfstream_setup_idle(mailstream * s)
static int mailstream_low_cfstream_setup_idle(mailstream_low * s)
{
#if HAVE_CFNETWORK
struct mailstream_cfstream_data * cfstream_data;
cfstream_data = (struct mailstream_cfstream_data *) s->low->data;
cfstream_data = (struct mailstream_cfstream_data *) s->data;
cfstream_data->idleInterrupted = false;
cfstream_data->idleInterruptedContext.info = s;
cfstream_data->idleInterruptedContext.perform = idleInterruptedPerform;
cfstream_data->idleInterruptedSource = CFRunLoopSourceCreate(NULL, 0, &cfstream_data->idleInterruptedContext);
return 0;
#else
return -1;
#endif
}
void mailstream_cfstream_unsetup_idle(mailstream * s)
static int mailstream_low_cfstream_unsetup_idle(mailstream_low * s)
{
#if HAVE_CFNETWORK
struct mailstream_cfstream_data * cfstream_data;
cfstream_data = (struct mailstream_cfstream_data *) s->low->data;
cfstream_data = (struct mailstream_cfstream_data *) s->data;
if (cfstream_data->idleInterruptedSource != NULL) {
CFRelease(cfstream_data->idleInterruptedSource);
cfstream_data->idleInterruptedSource = NULL;
}
return 0;
#else
return -1;
#endif
}
void mailstream_cfstream_interrupt_idle(mailstream * s)
static int mailstream_low_cfstream_interrupt_idle(mailstream_low * s)
{
#if HAVE_CFNETWORK
struct mailstream_cfstream_data * cfstream_data;
cfstream_data = (struct mailstream_cfstream_data *) s->low->data;
cfstream_data = (struct mailstream_cfstream_data *) s->data;
pthread_mutex_lock(&cfstream_data->runloop_lock);
@ -1126,6 +1138,9 @@ void mailstream_cfstream_interrupt_idle(mailstream * s)
}
pthread_mutex_unlock(&cfstream_data->runloop_lock);
return 0;
#else
return -1;
#endif
}

View File

@ -96,10 +96,11 @@ extern "C" {
int mailstream_low_cfstream_wait_idle(mailstream_low * low, int max_idle_delay);
/* in main thread */
void mailstream_cfstream_setup_idle(mailstream * s);
void mailstream_cfstream_interrupt_idle(mailstream * s);
void mailstream_cfstream_unsetup_idle(mailstream * s);
/*
void mailstream_low_cfstream_setup_idle(mailstream_low * s);
void mailstream_low_cfstream_interrupt_idle(mailstream_low * s);
void mailstream_low_cfstream_unsetup_idle(mailstream_low * s);
*/
/* SSL certificate */
#ifdef __cplusplus

View File

@ -63,6 +63,9 @@ static struct mailstream_cancel * mailstream_low_compress_get_cancel(mailstream_
static void mailstream_low_compress_free(mailstream_low * s);
static void mailstream_low_compress_cancel(mailstream_low * s);
static carray * mailstream_low_compress_get_certificate_chain(mailstream_low * s);
static int mailstream_low_compress_setup_idle(mailstream_low * low);
static int mailstream_low_compress_unsetup_idle(mailstream_low * low);
static int mailstream_low_compress_interrupt_idle(mailstream_low * low);
#if HAVE_ZLIB
typedef struct mailstream_compress_data {
@ -83,6 +86,9 @@ static mailstream_low_driver local_mailstream_compress_driver = {
/* mailstream_cancel */ mailstream_low_compress_cancel,
/* mailstream_get_cancel */ mailstream_low_compress_get_cancel,
/* mailstream_get_certificate_chain */ mailstream_low_compress_get_certificate_chain,
/* mailstream_setup_idle */ mailstream_low_compress_setup_idle,
/* mailstream_unsetup_idle */ mailstream_low_compress_unsetup_idle,
/* mailstream_interrupt_idle */ mailstream_low_compress_interrupt_idle,
};
mailstream_low_driver * mailstream_compress_driver = &local_mailstream_compress_driver;
@ -311,3 +317,33 @@ int mailstream_low_compress_wait_idle(mailstream_low * low,
return MAILSTREAM_IDLE_ERROR;
#endif
}
static int mailstream_low_compress_setup_idle(mailstream_low * low)
{
#if HAVE_ZLIB
compress_data * data = low->data;
return mailstream_low_setup_idle(data->ms);
#else
return -1;
#endif
}
static int mailstream_low_compress_unsetup_idle(mailstream_low * low)
{
#if HAVE_ZLIB
compress_data * data = low->data;
return mailstream_low_unsetup_idle(data->ms);
#else
return -1;
#endif
}
static int mailstream_low_compress_interrupt_idle(mailstream_low * low)
{
#if HAVE_ZLIB
compress_data * data = low->data;
return mailstream_low_interrupt_idle(data->ms);
#else
return -1;
#endif
}

View File

@ -55,4 +55,15 @@ int mailstream_low_compress_wait_idle(mailstream_low * low,
struct mailstream_cancel * idle,
int max_idle_delay);
/*
LIBETPAN_EXPORT
int mailstream_low_compress_setup_idle(mailstream_low * low);
LIBETPAN_EXPORT
int mailstream_low_compress_unsetup_idle(mailstream_low * low);
LIBETPAN_EXPORT
int mailstream_low_compress_interrupt_idle(mailstream_low * low);
*/
#endif

View File

@ -488,3 +488,28 @@ int mailstream_low_wait_idle(mailstream_low * low, struct mailstream_cancel * id
return MAILSTREAM_IDLE_ERROR;
}
}
int mailstream_low_setup_idle(mailstream_low * low)
{
if (low->driver->mailstream_setup_idle == NULL)
return -1;
return low->driver->mailstream_setup_idle(low);
}
int mailstream_low_unsetup_idle(mailstream_low * low)
{
if (low->driver->mailstream_unsetup_idle == NULL)
return -1;
return low->driver->mailstream_unsetup_idle(low);
}
int mailstream_low_interrupt_idle(mailstream_low * low)
{
if (low->driver->mailstream_interrupt_idle == NULL)
return -1;
return low->driver->mailstream_interrupt_idle(low);
}

View File

@ -84,20 +84,38 @@ int mailstream_low_set_identifier(mailstream_low * s,
LIBETPAN_EXPORT
const char * mailstream_low_get_identifier(mailstream_low * s);
LIBETPAN_EXPORT
void mailstream_low_set_timeout(mailstream_low * s,
time_t timeout);
LIBETPAN_EXPORT
time_t mailstream_low_get_timeout(mailstream_low * s);
LIBETPAN_EXPORT
void mailstream_low_set_logger(mailstream_low * s, void (* logger)(mailstream_low * s, int log_type,
const char * str, size_t size, void * context), void * logger_context);
/* Get certificate chain. Returns an array of MMAPString containing DER data or NULL if it's not a SSL connection */
LIBETPAN_EXPORT
carray * mailstream_low_get_certificate_chain(mailstream_low * s);
LIBETPAN_EXPORT
int mailstream_low_wait_idle(mailstream_low * low, struct mailstream_cancel * cancel,
int max_idle_delay);
/*
All those functions returns -1 if interrupt idle is not implemented and
should be based on select().
*/
LIBETPAN_EXPORT
int mailstream_low_setup_idle(mailstream_low * low);
LIBETPAN_EXPORT
int mailstream_low_unsetup_idle(mailstream_low * low);
LIBETPAN_EXPORT
int mailstream_low_interrupt_idle(mailstream_low * low);
#ifdef __cplusplus
}
#endif

View File

@ -96,6 +96,9 @@ static mailstream_low_driver local_mailstream_socket_driver = {
/* mailstream_cancel */ mailstream_low_socket_cancel,
/* mailstream_get_cancel */ mailstream_low_socket_get_cancel,
/* mailstream_get_certificate_chain */ NULL,
/* mailstream_setup_idle */ NULL,
/* mailstream_unsetup_idle */ NULL,
/* mailstream_interrupt_idle */ NULL,
};
mailstream_low_driver * mailstream_socket_driver =

View File

@ -360,6 +360,9 @@ static mailstream_low_driver local_mailstream_ssl_driver = {
/* mailstream_cancel */ mailstream_low_ssl_cancel,
/* mailstream_get_cancel */ mailstream_low_ssl_get_cancel,
/* mailstream_get_certificate_chain */ mailstream_low_ssl_get_certificate_chain,
/* mailstream_setup_idle */ NULL,
/* mailstream_unsetup_idle */ NULL,
/* mailstream_interrupt_idle */ NULL,
};
mailstream_low_driver * mailstream_ssl_driver = &local_mailstream_ssl_driver;

View File

@ -99,6 +99,10 @@ struct mailstream_low_driver {
struct mailstream_cancel * (* mailstream_get_cancel)(mailstream_low *);
/* Returns an array of MMAPString containing DER data or NULL if it's not a SSL connection */
carray * (* mailstream_get_certificate_chain)(mailstream_low *);
/* Will be called from the main thread */
int (* mailstream_setup_idle)(mailstream_low *);
int (* mailstream_unsetup_idle)(mailstream_low *);
int (* mailstream_interrupt_idle)(mailstream_low *);
};
typedef struct mailstream_low_driver mailstream_low_driver;