Laaaaaaadiesssss and gentlement... WE HAVE A WINNER!!! On 04/03/2012 01:57 AM, Angus Salkeld wrote: > Sometimes calling xyz_finilize() within a dispatch would > cause a crash because the qb_ipcc_disconnect actually > disconnects immediatly and frees it't memory. whereas > the corosync structure is reference counted. So this > makes use of the reference counting to only call > qb_ipcc_disconnect when it is fully dereferenced. > > Signed-off-by: Angus Salkeld <asalkeld@xxxxxxxxxx> > --- > lib/cfg.c | 20 +++++++++++++++++--- > lib/cmap.c | 25 +++++++++++++++++++++++-- > lib/cpg.c | 20 +++++++++++++++++--- > lib/quorum.c | 22 +++++++++++++++++----- > lib/votequorum.c | 21 +++++++++++++++++---- > 5 files changed, 91 insertions(+), 17 deletions(-) > > diff --git a/lib/cfg.c b/lib/cfg.c > index 34b8ea4..248df4d 100644 > --- a/lib/cfg.c > +++ b/lib/cfg.c > @@ -72,7 +72,9 @@ struct cfg_inst { > /* > * All instances in one database > */ > -DECLARE_HDB_DATABASE (cfg_hdb,NULL); > +static void cfg_inst_free (void *inst); > + > +DECLARE_HDB_DATABASE (cfg_hdb, cfg_inst_free); > > /* > * Implementation > @@ -96,6 +98,7 @@ corosync_cfg_initialize ( > goto error_destroy; > } > > + cfg_inst->finalize = 0; > cfg_inst->c = qb_ipcc_connect ("cfg", IPC_REQUEST_SIZE); > if (cfg_inst->c == NULL) { > error = qb_to_cs_error(-errno); > @@ -218,6 +221,13 @@ corosync_cfg_dispatch ( > goto error_nounlock; > break; > } > + if (cfg_inst->finalize) { > + /* > + * If the finalize has been called then get out of the dispatch. > + */ > + error = CS_ERR_BAD_HANDLE; > + goto error_put; > + } > > /* > * Determine if more messages should be processed > @@ -233,6 +243,12 @@ error_nounlock: > return (error); > } > > +static void cfg_inst_free (void *inst) > +{ > + struct cfg_inst *cfg_inst = (struct cfg_inst *)inst; > + qb_ipcc_disconnect(cfg_inst->c); > +} > + > cs_error_t > corosync_cfg_finalize ( > corosync_cfg_handle_t cfg_handle) > @@ -255,8 +271,6 @@ corosync_cfg_finalize ( > > cfg_inst->finalize = 1; > > - qb_ipcc_disconnect (cfg_inst->c); > - > (void)hdb_handle_destroy (&cfg_hdb, cfg_handle); > > (void)hdb_handle_put (&cfg_hdb, cfg_handle); > diff --git a/lib/cmap.c b/lib/cmap.c > index 1a58541..bfe7d6e 100644 > --- a/lib/cmap.c > +++ b/lib/cmap.c > @@ -54,6 +54,7 @@ > #include <stdio.h> > > struct cmap_inst { > + int finalize; > qb_ipcc_connection_t *c; > const void *context; > }; > @@ -65,7 +66,9 @@ struct cmap_track_inst { > cmap_track_handle_t track_handle; > }; > > -DECLARE_HDB_DATABASE(cmap_handle_t_db,NULL); > +static void cmap_inst_free (void *inst); > + > +DECLARE_HDB_DATABASE(cmap_handle_t_db, cmap_inst_free); > DECLARE_HDB_DATABASE(cmap_track_handle_t_db,NULL); > > /* > @@ -99,6 +102,7 @@ cs_error_t cmap_initialize (cmap_handle_t *handle) > } > > error = CS_OK; > + cmap_inst->finalize = 0; > cmap_inst->c = qb_ipcc_connect("cmap", IPC_REQUEST_SIZE); > if (cmap_inst->c == NULL) { > error = qb_to_cs_error(-errno); > @@ -117,6 +121,12 @@ error_no_destroy: > return (error); > } > > +static void cmap_inst_free (void *inst) > +{ > + struct cmap_inst *cmap_inst = (struct cmap_inst *)inst; > + qb_ipcc_disconnect(cmap_inst->c); > +} > + > cs_error_t cmap_finalize(cmap_handle_t handle) > { > struct cmap_inst *cmap_inst; > @@ -129,7 +139,11 @@ cs_error_t cmap_finalize(cmap_handle_t handle) > return (error); > } > > - qb_ipcc_disconnect(cmap_inst->c); > + if (cmap_inst->finalize) { > + (void)hdb_handle_put (&cmap_handle_t_db, handle); > + return (CS_ERR_BAD_HANDLE); > + } > + cmap_inst->finalize = 1; > > /* > * Destroy all track instances for given connection > @@ -270,6 +284,13 @@ cs_error_t cmap_dispatch ( > goto error_put; > break; > } > + if (cmap_inst->finalize) { > + /* > + * If the finalize has been called then get out of the dispatch. > + */ > + error = CS_ERR_BAD_HANDLE; > + goto error_put; > + } > > /* > * Determine if more messages should be processed > diff --git a/lib/cpg.c b/lib/cpg.c > index 700303f..0c9fa1a 100644 > --- a/lib/cpg.c > +++ b/lib/cpg.c > @@ -73,8 +73,9 @@ struct cpg_inst { > }; > struct list_head iteration_list_head; > }; > +static void cpg_inst_free (void *inst); > > -DECLARE_HDB_DATABASE(cpg_handle_t_db,NULL); > +DECLARE_HDB_DATABASE(cpg_handle_t_db, cpg_inst_free); > > struct cpg_iteration_instance_t { > cpg_iteration_handle_t cpg_iteration_handle; > @@ -108,6 +109,12 @@ static void cpg_iteration_instance_finalize (struct cpg_iteration_instance_t *cp > hdb_handle_destroy (&cpg_iteration_handle_t_db, cpg_iteration_instance->cpg_iteration_handle); > } > > +static void cpg_inst_free (void *inst) > +{ > + struct cpg_inst *cpg_inst = (struct cpg_inst *)inst; > + qb_ipcc_disconnect(cpg_inst->c); > +} > + > static void cpg_inst_finalize (struct cpg_inst *cpg_inst, hdb_handle_t handle) > { > struct list_head *iter, *iter_next; > @@ -248,8 +255,6 @@ cs_error_t cpg_finalize ( > &res_lib_cpg_finalize, > sizeof (struct res_lib_cpg_finalize)); > > - qb_ipcc_disconnect(cpg_inst->c); > - > cpg_inst_finalize (cpg_inst, handle); > hdb_handle_put (&cpg_handle_t_db, handle); > > @@ -475,6 +480,15 @@ cs_error_t cpg_dispatch ( > break; /* case CPG_MODEL_V1 */ > } /* - switch (cpg_inst_copy.model_data.model) */ > > + if (cpg_inst_copy.finalize || cpg_inst->finalize) { > + /* > + * If the finalize has been called then get out of the dispatch. > + */ > + cpg_inst->finalize = 1; > + error = CS_ERR_BAD_HANDLE; > + goto error_put; > + } > + > /* > * Determine if more messages should be processed > */ > diff --git a/lib/quorum.c b/lib/quorum.c > index 1ee2f06..eb53b7f 100644 > --- a/lib/quorum.c > +++ b/lib/quorum.c > @@ -61,7 +61,9 @@ struct quorum_inst { > quorum_callbacks_t callbacks; > }; > > -DECLARE_HDB_DATABASE(quorum_handle_t_db,NULL); > +static void quorum_inst_free (void *inst); > + > +DECLARE_HDB_DATABASE(quorum_handle_t_db, quorum_inst_free); > > cs_error_t quorum_initialize ( > quorum_handle_t *handle, > @@ -85,6 +87,7 @@ cs_error_t quorum_initialize ( > } > > error = CS_OK; > + quorum_inst->finalize = 0; > quorum_inst->c = qb_ipcc_connect ("quorum", IPC_REQUEST_SIZE); > if (quorum_inst->c == NULL) { > error = qb_to_cs_error(-errno); > @@ -129,6 +132,12 @@ error_no_destroy: > return (error); > } > > +static void quorum_inst_free (void *inst) > +{ > + struct quorum_inst *quorum_inst = (struct quorum_inst *)inst; > + qb_ipcc_disconnect(quorum_inst->c); > +} > + > cs_error_t quorum_finalize ( > quorum_handle_t handle) > { > @@ -150,8 +159,6 @@ cs_error_t quorum_finalize ( > > quorum_inst->finalize = 1; > > - qb_ipcc_disconnect (quorum_inst->c); > - > (void)hdb_handle_destroy (&quorum_handle_t_db, handle); > > (void)hdb_handle_put (&quorum_handle_t_db, handle); > @@ -433,6 +440,13 @@ cs_error_t quorum_dispatch ( > goto error_put; > break; > } > + if (quorum_inst->finalize) { > + /* > + * If the finalize has been called then get out of the dispatch. > + */ > + error = CS_ERR_BAD_HANDLE; > + goto error_put; > + } > > /* > * Determine if more messages should be processed > @@ -442,8 +456,6 @@ cs_error_t quorum_dispatch ( > } > } while (cont); > > - goto error_put; > - > error_put: > (void)hdb_handle_put (&quorum_handle_t_db, handle); > return (error); > diff --git a/lib/votequorum.c b/lib/votequorum.c > index 6240f99..e2b578f 100644 > --- a/lib/votequorum.c > +++ b/lib/votequorum.c > @@ -64,7 +64,9 @@ struct votequorum_inst { > votequorum_callbacks_t callbacks; > }; > > -DECLARE_HDB_DATABASE(votequorum_handle_t_db,NULL); > +static void votequorum_inst_free (void *inst); > + > +DECLARE_HDB_DATABASE(votequorum_handle_t_db, votequorum_inst_free); > > cs_error_t votequorum_initialize ( > votequorum_handle_t *handle, > @@ -83,6 +85,7 @@ cs_error_t votequorum_initialize ( > goto error_destroy; > } > > + votequorum_inst->finalize = 0; > votequorum_inst->c = qb_ipcc_connect ("votequorum", IPC_REQUEST_SIZE); > if (votequorum_inst->c == NULL) { > error = qb_to_cs_error(-errno); > @@ -106,6 +109,12 @@ error_no_destroy: > return (error); > } > > +static void votequorum_inst_free (void *inst) > +{ > + struct votequorum_inst *vq_inst = (struct votequorum_inst *)inst; > + qb_ipcc_disconnect(vq_inst->c); > +} > + > cs_error_t votequorum_finalize ( > votequorum_handle_t handle) > { > @@ -127,8 +136,6 @@ cs_error_t votequorum_finalize ( > > votequorum_inst->finalize = 1; > > - qb_ipcc_disconnect (votequorum_inst->c); > - > hdb_handle_destroy (&votequorum_handle_t_db, handle); > > hdb_handle_put (&votequorum_handle_t_db, handle); > @@ -521,6 +528,13 @@ cs_error_t votequorum_dispatch ( > goto error_put; > break; > } > + if (votequorum_inst->finalize) { > + /* > + * If the finalize has been called then get out of the dispatch. > + */ > + error = CS_ERR_BAD_HANDLE; > + goto error_put; > + } > > /* > * Determine if more messages should be processed > @@ -530,7 +544,6 @@ cs_error_t votequorum_dispatch ( > } > } while (cont); > > - goto error_put; > > error_put: > hdb_handle_put (&votequorum_handle_t_db, handle); _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss