summaryrefslogtreecommitdiffstats
path: root/src/indmanager
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2013-11-04 16:28:06 +0100
committerTomas Bzatek <tbzatek@redhat.com>2013-11-04 16:52:09 +0100
commit8e8c32b6a1f9332eaf3697fc3dd8e2a6ead397ec (patch)
tree43c8da7587b463c52165bf655f56faa4540f4c68 /src/indmanager
parent834582da22be09cf318d988c18e20f73d766116f (diff)
downloadopenlmi-providers-8e8c32b6a1f9332eaf3697fc3dd8e2a6ead397ec.tar.gz
openlmi-providers-8e8c32b6a1f9332eaf3697fc3dd8e2a6ead397ec.tar.xz
openlmi-providers-8e8c32b6a1f9332eaf3697fc3dd8e2a6ead397ec.zip
indmanager: Use per-instance set of pthread stuff
Can't really have global variables for threads and mutexes as long as there are more indication managers running, simultaneously using the same objects, leading to deadlock in a matter of time. This patch moves the pthread stuff in the IMManager struct which is (usually) speficic to each CIM indication class.
Diffstat (limited to 'src/indmanager')
-rw-r--r--src/indmanager/ind_manager.c74
-rw-r--r--src/indmanager/ind_manager.h5
2 files changed, 39 insertions, 40 deletions
diff --git a/src/indmanager/ind_manager.c b/src/indmanager/ind_manager.c
index 525d2f8..7eb7b55 100644
--- a/src/indmanager/ind_manager.c
+++ b/src/indmanager/ind_manager.c
@@ -71,12 +71,6 @@ typedef enum _IMIDiff {
IMIDiff compare_instances(CMPIInstance *, CMPIInstance *);
bool maybe_remove_polled(IMManager *, CMPIObjectPath *, IMError *);
-/* For threading purposes */
-pthread_t _t_manage;
-pthread_mutex_t _t_mutex;
-pthread_mutexattr_t _t_mutex_attr;
-pthread_cond_t _t_cond;
-
/* CMPI rc handler */
CMPIStatus im_rc;
@@ -677,34 +671,34 @@ static void *manage(void *data)
while (1) {
DEBUG("manage thread in infinite loop");
// wait until manager is running
- pthread_mutex_lock(&_t_mutex);
+ pthread_mutex_lock(&manager->_t_mutex);
while (!manager->running) {
DEBUG("manage thread waiting to indication start");
- pthread_cond_wait(&_t_cond, &_t_mutex);
+ pthread_cond_wait(&manager->_t_cond, &manager->_t_mutex);
}
if (manager->polling) {
if (!first_poll(manager, &err)) {
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return (void *)err;
}
}
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
DEBUG("manage thread calling watcher");
if(!manager->watcher(&manager->data)) {
continue;
}
- pthread_mutex_lock(&_t_mutex);
+ pthread_mutex_lock(&manager->_t_mutex);
if (manager->polling) {
// poll enumerations
if (!_im_poll(manager, &err)) {
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return (void *)err;
}
// create list of diffs
if (!gen_diffs(manager, &diffs, &err)) {
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return (void *)err;
}
manager->data = &diffs;
@@ -713,7 +707,7 @@ static void *manage(void *data)
while (manager->gather(manager, &iold, &inew, manager->data)) {
send_indication(iold, inew, manager);
}
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
}
}
@@ -832,10 +826,10 @@ IMManager* im_create_manager(IMInstGather gather, IMFilterChecker f_checker,
manager->data = NULL;
DEBUG("Manager created");
- if (pthread_mutexattr_init(&_t_mutex_attr) ||
- pthread_mutexattr_settype(&_t_mutex_attr, PTHREAD_MUTEX_ERRORCHECK) ||
- pthread_mutex_init(&_t_mutex, &_t_mutex_attr) ||
- pthread_cond_init(&_t_cond, NULL)) {
+ if (pthread_mutexattr_init(&manager->_t_mutex_attr) ||
+ pthread_mutexattr_settype(&manager->_t_mutex_attr, PTHREAD_MUTEX_ERRORCHECK) ||
+ pthread_mutex_init(&manager->_t_mutex, &manager->_t_mutex_attr) ||
+ pthread_cond_init(&manager->_t_cond, NULL)) {
*err = IM_ERR_THREAD;
free(manager);
return NULL;
@@ -856,15 +850,15 @@ bool im_destroy_manager(IMManager *manager, const CMPIContext *ctx,
return false;
}
im_stop_ind(manager, ctx, err);
- pthread_mutex_lock(&_t_mutex);
+ pthread_mutex_lock(&manager->_t_mutex);
if (!remove_all_filters(manager, err)) {
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return false;
}
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
DEBUG("Destroying manager");
- if (pthread_mutex_destroy(&_t_mutex) ||
- pthread_mutexattr_destroy(&_t_mutex_attr)) {
+ if (pthread_mutex_destroy(&manager->_t_mutex) ||
+ pthread_mutexattr_destroy(&manager->_t_mutex_attr)) {
*err = IM_ERR_THREAD;
return false;
}
@@ -972,37 +966,37 @@ bool _im_add_filter(IMManager *manager, CMPISelectExp *se, IMError *err)
bool im_add_filter(IMManager *manager, CMPISelectExp *filter,
const CMPIContext *ctx, IMError *err)
{
- pthread_mutex_lock(&_t_mutex);
+ pthread_mutex_lock(&manager->_t_mutex);
if (!manager) {
*err = IM_ERR_MANAGER;
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return false;
}
if (!ctx) {
*err = IM_ERR_CONTEXT;
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return false;
}
if (!filter) {
*err = IM_ERR_FILTER;
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return false;
}
manager->ctx_main = ctx;
DEBUG("Adding filter");
if (!_im_add_filter(manager, filter, err)) {
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return false;
}
if (manager->polling) {
if (!add_enumeration(manager,
get_object_path(manager->broker, filter),
err)) {
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return false;
}
}
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return true;
}
@@ -1055,9 +1049,9 @@ bool im_remove_filter(IMManager *manager, const CMPISelectExp *filter,
*err = IM_ERR_FILTER;
return false;
}
- pthread_mutex_lock(&_t_mutex);
+ pthread_mutex_lock(&manager->_t_mutex);
if (!manager->filters) {
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
*err = IM_ERR_NOT_FOUND;
return false;
}
@@ -1075,20 +1069,20 @@ bool im_remove_filter(IMManager *manager, const CMPISelectExp *filter,
}
if (manager->polling && !maybe_remove_polled(manager, current->op,
err)) {
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return false;
}
CMRelease(current->op);
free(current->select_exp_string);
free(current);
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return true;
}
prev = current;
current = current->next;
}
*err = IM_ERR_NOT_FOUND;
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return false;
}
@@ -1112,13 +1106,13 @@ bool im_start_ind(IMManager *manager, const CMPIContext *ctx, IMError *err)
manager->ctx_manage = CBPrepareAttachThread(manager->broker,
manager->ctx_main);
DEBUG("Creating second thread");
- if (pthread_create(&_t_manage, NULL, manage, manager)) {
+ if (pthread_create(&manager->_t_manage, NULL, manage, manager)) {
*err = IM_ERR_THREAD;
return false;
}
DEBUG("Starting indications");
manager->running = true;
- pthread_cond_signal(&_t_cond);
+ pthread_cond_signal(&manager->_t_cond);
return true;
}
@@ -1138,11 +1132,11 @@ bool im_stop_ind(IMManager *manager, const CMPIContext *ctx, IMError *err)
manager->running = false;
/* No locking here due to potential deadlock */
- if (pthread_cancel(_t_manage)) {
+ if (pthread_cancel(manager->_t_manage)) {
*err = IM_ERR_THREAD;
return false;
}
- if (pthread_join(_t_manage, NULL)) {
+ if (pthread_join(manager->_t_manage, NULL)) {
*err = IM_ERR_THREAD;
return false;
}
@@ -1152,7 +1146,7 @@ bool im_stop_ind(IMManager *manager, const CMPIContext *ctx, IMError *err)
manager->data = NULL;
manager->ctx_manage = NULL;
/* Mutex could have been in locked state when the thread was canceled */
- pthread_mutex_unlock(&_t_mutex);
+ pthread_mutex_unlock(&manager->_t_mutex);
return true;
}
diff --git a/src/indmanager/ind_manager.h b/src/indmanager/ind_manager.h
index b82fa69..01aa2e5 100644
--- a/src/indmanager/ind_manager.h
+++ b/src/indmanager/ind_manager.h
@@ -139,6 +139,11 @@ struct _IMManager {
const CMPIContext *ctx_main; /* main thread */
CMPIContext *ctx_manage; /* manage thread */
IMEnumerations *enums;
+ // threading
+ pthread_t _t_manage;
+ pthread_mutex_t _t_mutex;
+ pthread_mutexattr_t _t_mutex_attr;
+ pthread_cond_t _t_cond;
// passed data, used for communication between gather/watcher/etc.
void *data;
};