Tell us how you really feel... ;) On 04/02/2012 09:54 PM, Fabio M. Di Nitto wrote: > 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 -- Digimer Papers and Projects: https://alteeve.com _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss