mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-19 08:11:21 +00:00
Read/write lockify the devicestate stuff a bit.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@53111 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user