Просмотр исходного кода

defect 591
If checkpoint open is called, but checkpoint close isn't called before
saCkptFinalize is called, the reference count of the checkpoints gets
out of kilter.

(Logical change 1.197)


git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@645 fd59a12c-fef9-0310-b244-a6a79926bd2f

Steven Dake 20 лет назад
Родитель
Сommit
4ad46bbf70
1 измененных файлов с 27 добавлено и 4 удалено
  1. 27 4
      lib/ckpt.c

+ 27 - 4
lib/ckpt.c

@@ -66,15 +66,18 @@ struct ckptInstance {
 	int finalize;
 	int finalize;
 	pthread_mutex_t response_mutex;
 	pthread_mutex_t response_mutex;
 	pthread_mutex_t dispatch_mutex;
 	pthread_mutex_t dispatch_mutex;
+	struct list_head checkpoint_list;
 };
 };
 
 
 struct ckptCheckpointInstance {
 struct ckptCheckpointInstance {
 	int response_fd;
 	int response_fd;
 	SaCkptHandleT ckptHandle;
 	SaCkptHandleT ckptHandle;
+	SaCkptCheckpointHandleT checkpointHandle;
 	SaCkptCheckpointOpenFlagsT checkpointOpenFlags;
 	SaCkptCheckpointOpenFlagsT checkpointOpenFlags;
 	SaNameT checkpointName;
 	SaNameT checkpointName;
 	SaUint32T maxSectionIdSize;
 	SaUint32T maxSectionIdSize;
 	pthread_mutex_t response_mutex;
 	pthread_mutex_t response_mutex;
+	struct list_head list;
 };
 };
 
 
 struct ckptSectionIterationInstance {
 struct ckptSectionIterationInstance {
@@ -198,6 +201,8 @@ saCkptInitialize (
 
 
 	memcpy (&ckptInstance->callbacks, callbacks, sizeof (SaCkptCallbacksT));
 	memcpy (&ckptInstance->callbacks, callbacks, sizeof (SaCkptCallbacksT));
 
 
+	list_init (&ckptInstance->checkpoint_list);
+
 	pthread_mutex_init (&ckptInstance->response_mutex, NULL);
 	pthread_mutex_init (&ckptInstance->response_mutex, NULL);
 
 
 	saHandleInstancePut (&ckptHandleDatabase, *ckptHandle);
 	saHandleInstancePut (&ckptHandleDatabase, *ckptHandle);
@@ -363,6 +368,8 @@ saCkptFinalize (
 {
 {
 	struct ckptInstance *ckptInstance;
 	struct ckptInstance *ckptInstance;
 	SaAisErrorT error;
 	SaAisErrorT error;
+	struct list_head *list;
+	struct ckptCheckpointInstance *ckptCheckpointInstance;
 
 
 	error = saHandleInstanceGet (&ckptHandleDatabase, ckptHandle,
 	error = saHandleInstanceGet (&ckptHandleDatabase, ckptHandle,
 		(void *)&ckptInstance);
 		(void *)&ckptInstance);
@@ -385,9 +392,21 @@ saCkptFinalize (
 
 
 	pthread_mutex_unlock (&ckptInstance->response_mutex);
 	pthread_mutex_unlock (&ckptInstance->response_mutex);
 
 
+
+	for (list = ckptInstance->checkpoint_list.next;
+		list != &ckptInstance->checkpoint_list;
+		list = list->next) {
+
+		ckptCheckpointInstance = list_entry (list,
+			struct ckptCheckpointInstance, list);
+
+		saHandleInstancePut (&checkpointHandleDatabase,
+			ckptCheckpointInstance->checkpointHandle);
+	}
+
 	saHandleInstancePut (&ckptHandleDatabase, ckptHandle);
 	saHandleInstancePut (&ckptHandleDatabase, ckptHandle);
 
 
-    saHandleDestroy (&ckptHandleDatabase, ckptHandle);
+	saHandleDestroy (&ckptHandleDatabase, ckptHandle);
 
 
 	return (SA_AIS_OK);
 	return (SA_AIS_OK);
 }
 }
@@ -413,8 +432,8 @@ saCkptCheckpointOpen (
 		goto error_no_destroy;
 		goto error_no_destroy;
 	}
 	}
 
 
-	error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
-		(void *)&ckptCheckpointInstance);
+	error = saHandleInstanceGet (&checkpointHandleDatabase,
+		*checkpointHandle, (void *)&ckptCheckpointInstance);
 	if (error != SA_AIS_OK) {
 	if (error != SA_AIS_OK) {
 		goto error_destroy;
 		goto error_destroy;
 	}
 	}
@@ -431,6 +450,7 @@ saCkptCheckpointOpen (
 		checkpointCreationAttributes->maxSectionIdSize;
 		checkpointCreationAttributes->maxSectionIdSize;
 
 
 	ckptCheckpointInstance->ckptHandle = ckptHandle;
 	ckptCheckpointInstance->ckptHandle = ckptHandle;
+	ckptCheckpointInstance->checkpointHandle = *checkpointHandle;
 	ckptCheckpointInstance->checkpointOpenFlags = checkpointOpenFlags;
 	ckptCheckpointInstance->checkpointOpenFlags = checkpointOpenFlags;
 
 
 	req_lib_ckpt_checkpointopen.header.size = sizeof (struct req_lib_ckpt_checkpointopen);
 	req_lib_ckpt_checkpointopen.header.size = sizeof (struct req_lib_ckpt_checkpointopen);
@@ -463,6 +483,7 @@ saCkptCheckpointOpen (
 
 
 	saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
 	saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
 
 
+	list_add (&ckptCheckpointInstance->list, &ckptInstance->checkpoint_list);
 	return (error);
 	return (error);
 
 
 error_put_ckpt_destroy:
 error_put_ckpt_destroy:
@@ -578,9 +599,11 @@ saCkptCheckpointClose (
 		sizeof (struct res_lib_ckpt_checkpointclose), MSG_WAITALL | MSG_NOSIGNAL);
 		sizeof (struct res_lib_ckpt_checkpointclose), MSG_WAITALL | MSG_NOSIGNAL);
 
 
 
 
+	list_del (&ckptCheckpointInstance->list);
+
 	saHandleInstancePut (&ckptHandleDatabase, ckptCheckpointInstance->ckptHandle);
 	saHandleInstancePut (&ckptHandleDatabase, ckptCheckpointInstance->ckptHandle);
 
 
-    saHandleDestroy (&checkpointHandleDatabase, checkpointHandle);
+	saHandleDestroy (&checkpointHandleDatabase, checkpointHandle);
 
 
 exit_put:
 exit_put:
 	saHandleInstancePut (&checkpointHandleDatabase, checkpointHandle);
 	saHandleInstancePut (&checkpointHandleDatabase, checkpointHandle);