CVS commit by ossi: move whole responsibility for recycling open stores/server connections to the drivers.
M +51 -12 drv_imap.c 1.22 M +18 -7 drv_maildir.c 1.15 M +6 -2 isync.h 1.58 M +12 -22 main.c 1.56 --- isync/src/drv_imap.c #1.21:1.22 @@ -1037,5 +1037,5 @@ get_cmd_result( imap_store_t *ctx, struc static void -imap_close_store( store_t *gctx ) +imap_cancel_store( store_t *gctx ) { imap_store_t *ctx = (imap_store_t *)gctx; @@ -1043,8 +1043,6 @@ imap_close_store( store_t *gctx ) free_generic_messages( gctx->msgs ); free_string_list( ctx->gen.boxes ); - if (ctx->buf.sock.fd != -1) { - imap_exec( ctx, 0, "LOGOUT" ); + if (ctx->buf.sock.fd >= 0) close( ctx->buf.sock.fd ); - } #ifdef HAVE_LIBSSL if (ctx->SSLContext) @@ -1057,4 +1055,40 @@ imap_close_store( store_t *gctx ) } +static store_t *unowned; + +static void +imap_disown_store( store_t *gctx ) +{ + free_generic_messages( gctx->msgs ); + gctx->msgs = 0; + gctx->next = unowned; + unowned = gctx; +} + +static store_t * +imap_own_store( store_conf_t *conf ) +{ + store_t *store, **storep; + + for (storep = &unowned; (store = *storep); storep = &store->next) + if (store->conf == conf) { + *storep = store->next; + return store; + } + return 0; +} + +static void +imap_cleanup( void ) +{ + store_t *ctx, *nctx; + + for (ctx = unowned; ctx; ctx = nctx) { + nctx = ctx->next; + imap_exec( (imap_store_t *)ctx, 0, "LOGOUT" ); + imap_cancel_store( ctx ); + } +} + #ifdef HAVE_LIBSSL static int @@ -1166,9 +1200,10 @@ do_cram_auth( imap_store_t *ctx, struct static store_t * -imap_open_store( store_conf_t *conf, store_t *oldctx ) +imap_open_store( store_conf_t *conf ) { imap_store_conf_t *cfg = (imap_store_conf_t *)conf; imap_server_conf_t *srvc = cfg->server; - imap_store_t *ctx = (imap_store_t *)oldctx; + imap_store_t *ctx; + store_t **ctxp; char *arg, *rsp; struct hostent *he; @@ -1179,6 +1214,9 @@ imap_open_store( store_conf_t *conf, sto #endif - if (ctx) { - if (((imap_store_conf_t *)(ctx->gen.conf))->server == cfg->server) { + for (ctxp = &unowned; (ctx = (imap_store_t *)*ctxp); ctxp = &ctx->gen.next) + if (((imap_store_conf_t *)ctx->gen.conf)->server == srvc) { + *ctxp = ctx->gen.next; + /* One could ping the server here, but given that the idle timeout + * is at least 30 minutes, this sounds pretty pointless. */ free_string_list( ctx->gen.boxes ); ctx->gen.boxes = 0; @@ -1187,6 +1225,4 @@ imap_open_store( store_conf_t *conf, sto goto final; } - imap_close_store( &ctx->gen ); - } ctx = nfcalloc( sizeof(*ctx) ); @@ -1373,5 +1409,5 @@ imap_open_store( store_conf_t *conf, sto bail: - imap_close_store( &ctx->gen ); + imap_cancel_store( &ctx->gen ); return 0; } @@ -1740,6 +1776,9 @@ struct driver imap_driver = { DRV_CRLF, imap_parse_store, + imap_cleanup, imap_open_store, - imap_close_store, + imap_disown_store, + imap_own_store, + imap_cancel_store, imap_list, imap_prepare_paths, --- isync/src/drv_maildir.c #1.14:1.15 @@ -94,14 +94,10 @@ maildir_parse_flags( const char *base ) } -static void maildir_close_store( store_t *gctx ); - static store_t * -maildir_open_store( store_conf_t *conf, store_t *oldctx ) +maildir_open_store( store_conf_t *conf ) { maildir_store_t *ctx; struct stat st; - if (oldctx) - maildir_close_store( oldctx ); if (stat( conf->path, &st ) || !S_ISDIR(st.st_mode)) { error( "Maildir error: cannot open store %s\n", conf->path ); @@ -145,5 +141,5 @@ maildir_cleanup( store_t *gctx ) static void -maildir_close_store( store_t *gctx ) +maildir_disown_store( store_t *gctx ) { maildir_cleanup( gctx ); @@ -152,4 +148,16 @@ maildir_close_store( store_t *gctx ) } +static store_t * +maildir_own_store( store_conf_t *conf ) +{ + (void)conf; + return 0; +} + +static void +maildir_cleanup_drv( void ) +{ +} + static int maildir_list( store_t *gctx ) @@ -1227,6 +1235,9 @@ struct driver maildir_driver = { 0, maildir_parse_store, + maildir_cleanup_drv, maildir_open_store, - maildir_close_store, + maildir_disown_store, + maildir_own_store, + maildir_disown_store, /* _cancel_, but it's the same */ maildir_list, maildir_prepare_paths, --- isync/src/isync.h #1.57:1.58 @@ -144,4 +144,5 @@ typedef struct message { typedef struct store { + struct store *next; store_conf_t *conf; /* foreign */ string_list_t *boxes; /* _list results - own */ @@ -177,6 +178,9 @@ struct driver { int flags; int (*parse_store)( conffile_t *cfg, store_conf_t **storep, int *err ); - store_t *(*open_store)( store_conf_t *conf, store_t *oldctx ); - void (*close_store)( store_t *ctx ); + void (*cleanup)( void ); + store_t *(*open_store)( store_conf_t *conf ); + void (*disown_store)( store_t *ctx ); + store_t *(*own_store)( store_conf_t *conf ); + void (*cancel_store)( store_t *ctx ); int (*list)( store_t *ctx ); void (*prepare_paths)( store_t *ctx ); --- isync/src/main.c #1.55:1.56 @@ -191,5 +191,4 @@ main( int argc, char **argv ) { channel_conf_t *chan; - store_conf_t *conf[2]; group_conf_t *group; driver_t *driver[2]; @@ -442,7 +441,4 @@ main( int argc, char **argv ) chan = channels; chanptr = 0; - ctx[M] = ctx[S] = 0; - conf[M] = conf[S] = 0; /* make-gcc-happy */ - driver[M] = driver[S] = 0; /* make-gcc-happy */ if (all) multiple = channels->next != 0; @@ -487,21 +483,13 @@ main( int argc, char **argv ) boxes[M] = boxes[S] = cboxes = 0; - /* possible todo: handle master <-> slave swaps */ for (t = 0; t < 2; t++) { - if (ctx[t]) { - if (conf[t] == chan->stores[t]) - continue; - if (conf[t]->driver != chan->stores[t]->driver) { - driver[t]->close_store( ctx[t] ); - ctx[t] = 0; - } + driver[t] = chan->stores[t]->driver; + ctx[t] = driver[t]->own_store( chan->stores[t] ); } - conf[t] = chan->stores[t]; - driver[t] = conf[t]->driver; - if (!(ctx[t] = driver[t]->open_store( chan->stores[t], ctx[t] ))) { + for (t = 0; t < 2; t++) + if (!ctx[t] && !(ctx[t] = driver[t]->open_store( chan->stores[t] ))) { ret = 1; goto next; } - } info( "Channel %s\n", chan->name ); if (list && multiple) @@ -524,5 +512,5 @@ main( int argc, char **argv ) if (driver[t]->list( ctx[t] ) != DRV_OK) { screwt: - driver[t]->close_store( ctx[t] ); + driver[t]->cancel_store( ctx[t] ); ctx[t] = 0; ret = 1; @@ -585,4 +573,8 @@ main( int argc, char **argv ) free_string_list( boxes[M] ); free_string_list( boxes[S] ); + if (ctx[M]) + driver[M]->disown_store( ctx[M] ); + if (ctx[S]) + driver[S]->disown_store( ctx[S] ); if (all) { if (!(chan = chan->next)) @@ -596,8 +588,6 @@ main( int argc, char **argv ) } } - if (ctx[S]) - driver[S]->close_store( ctx[S] ); - if (ctx[M]) - driver[M]->close_store( ctx[M] ); + for (t = 0; t < N_DRIVERS; t++) + drivers[t]->cleanup(); return ret; ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 _______________________________________________ isync-devel mailing list isync-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/isync-devel