Read/write lockify the devicestate stuff a bit.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@53111 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.0
Joshua Colp 19 years ago
parent cfe66e6b26
commit ae64c71d65

@ -144,21 +144,21 @@ static const char *devstatestring[] = {
struct devstate_prov { struct devstate_prov {
char label[40]; char label[40];
ast_devstate_prov_cb_type callback; ast_devstate_prov_cb_type callback;
AST_LIST_ENTRY(devstate_prov) list; AST_RWLIST_ENTRY(devstate_prov) list;
}; };
/*! \brief A list of providers */ /*! \brief A list of providers */
static AST_LIST_HEAD_STATIC(devstate_provs, devstate_prov); static AST_RWLIST_HEAD_STATIC(devstate_provs, devstate_prov);
/*! \brief A device state watcher (callback) */ /*! \brief A device state watcher (callback) */
struct devstate_cb { struct devstate_cb {
void *data; void *data;
ast_devstate_cb_type callback; /*!< Where to report when state changes */ ast_devstate_cb_type callback; /*!< Where to report when state changes */
AST_LIST_ENTRY(devstate_cb) list; AST_RWLIST_ENTRY(devstate_cb) list;
}; };
/*! \brief A device state watcher list */ /*! \brief A device state watcher list */
static AST_LIST_HEAD_STATIC(devstate_cbs, devstate_cb); static AST_RWLIST_HEAD_STATIC(devstate_cbs, devstate_cb);
struct state_change { struct state_change {
AST_LIST_ENTRY(state_change) list; AST_LIST_ENTRY(state_change) list;
@ -277,9 +277,9 @@ int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
devprov->callback = callback; devprov->callback = callback;
ast_copy_string(devprov->label, label, sizeof(devprov->label)); ast_copy_string(devprov->label, label, sizeof(devprov->label));
AST_LIST_LOCK(&devstate_provs); AST_RWLIST_WRLOCK(&devstate_provs);
AST_LIST_INSERT_HEAD(&devstate_provs, devprov, list); AST_RWLIST_INSERT_HEAD(&devstate_provs, devprov, list);
AST_LIST_UNLOCK(&devstate_provs); AST_RWLIST_UNLOCK(&devstate_provs);
return 0; return 0;
} }
@ -289,16 +289,16 @@ void ast_devstate_prov_del(const char *label)
{ {
struct devstate_prov *devcb; struct devstate_prov *devcb;
AST_LIST_LOCK(&devstate_provs); AST_RWLIST_WRLOCK(&devstate_provs);
AST_LIST_TRAVERSE_SAFE_BEGIN(&devstate_provs, devcb, list) { AST_RWLIST_TRAVERSE_SAFE_BEGIN(&devstate_provs, devcb, list) {
if (!strcasecmp(devcb->label, label)) { if (!strcasecmp(devcb->label, label)) {
AST_LIST_REMOVE_CURRENT(&devstate_provs, list); AST_RWLIST_REMOVE_CURRENT(&devstate_provs, list);
free(devcb); free(devcb);
break; break;
} }
} }
AST_LIST_TRAVERSE_SAFE_END; AST_RWLIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&devstate_provs); AST_RWLIST_UNLOCK(&devstate_provs);
} }
/*! \brief Get provider device state */ /*! \brief Get provider device state */
@ -308,8 +308,8 @@ static int getproviderstate(const char *provider, const char *address)
int res = AST_DEVICE_INVALID; int res = AST_DEVICE_INVALID;
AST_LIST_LOCK(&devstate_provs); AST_RWLIST_RDLOCK(&devstate_provs);
AST_LIST_TRAVERSE_SAFE_BEGIN(&devstate_provs, devprov, list) { AST_RWLIST_TRAVERSE(&devstate_provs, devprov, list) {
if (option_debug > 4) if (option_debug > 4)
ast_log(LOG_DEBUG, "Checking provider %s with %s\n", devprov->label, provider); ast_log(LOG_DEBUG, "Checking provider %s with %s\n", devprov->label, provider);
@ -318,8 +318,7 @@ static int getproviderstate(const char *provider, const char *address)
break; break;
} }
} }
AST_LIST_TRAVERSE_SAFE_END; AST_RWLIST_UNLOCK(&devstate_provs);
AST_LIST_UNLOCK(&devstate_provs);
return res; return res;
} }
@ -334,9 +333,9 @@ int ast_devstate_add(ast_devstate_cb_type callback, void *data)
devcb->data = data; devcb->data = data;
devcb->callback = callback; devcb->callback = callback;
AST_LIST_LOCK(&devstate_cbs); AST_RWLIST_WRLOCK(&devstate_cbs);
AST_LIST_INSERT_HEAD(&devstate_cbs, devcb, list); AST_RWLIST_INSERT_HEAD(&devstate_cbs, devcb, list);
AST_LIST_UNLOCK(&devstate_cbs); AST_RWLIST_UNLOCK(&devstate_cbs);
return 0; return 0;
} }
@ -346,16 +345,16 @@ void ast_devstate_del(ast_devstate_cb_type callback, void *data)
{ {
struct devstate_cb *devcb; struct devstate_cb *devcb;
AST_LIST_LOCK(&devstate_cbs); AST_RWLIST_WRLOCK(&devstate_cbs);
AST_LIST_TRAVERSE_SAFE_BEGIN(&devstate_cbs, devcb, list) { AST_RWLIST_TRAVERSE_SAFE_BEGIN(&devstate_cbs, devcb, list) {
if ((devcb->callback == callback) && (devcb->data == data)) { if ((devcb->callback == callback) && (devcb->data == data)) {
AST_LIST_REMOVE_CURRENT(&devstate_cbs, list); AST_RWLIST_REMOVE_CURRENT(&devstate_cbs, list);
free(devcb); free(devcb);
break; break;
} }
} }
AST_LIST_TRAVERSE_SAFE_END; AST_RWLIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&devstate_cbs); AST_RWLIST_UNLOCK(&devstate_cbs);
} }
/*! \brief Notify callback watchers of change, and notify PBX core for hint updates /*! \brief Notify callback watchers of change, and notify PBX core for hint updates
@ -370,10 +369,10 @@ static void do_state_change(const char *device)
if (option_debug > 2) if (option_debug > 2)
ast_log(LOG_DEBUG, "Changing state for %s - state %d (%s)\n", device, state, devstate2str(state)); ast_log(LOG_DEBUG, "Changing state for %s - state %d (%s)\n", device, state, devstate2str(state));
AST_LIST_LOCK(&devstate_cbs); AST_RWLIST_RDLOCK(&devstate_cbs);
AST_LIST_TRAVERSE(&devstate_cbs, devcb, list) AST_RWLIST_TRAVERSE(&devstate_cbs, devcb, list)
devcb->callback(device, state, devcb->data); devcb->callback(device, state, devcb->data);
AST_LIST_UNLOCK(&devstate_cbs); AST_RWLIST_UNLOCK(&devstate_cbs);
ast_hint_state_changed(device); ast_hint_state_changed(device);
} }

Loading…
Cancel
Save