char *layer_key; /* layer + <tab>(0x09) + key */
gboolean reg;
GList *callbacks; /* data: bxt_noti_cb */
+ pthread_mutex_t cbs_lock;
};
struct bxt_noti_res {
GHashTable *req_cbs; /* key: msgid, value: bxt_req */
GHashTable *noti_cbs; /* key: keyname, value: bxt_noti */
+ pthread_mutex_t lock;
};
static GList *clients; /* data: buxton_client */
static pthread_mutex_t clients_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t noti_cbs_lock = PTHREAD_MUTEX_INITIALIZER;
static guint32 client_msgid;
static struct buxton_value *value_create(enum buxton_key_type type, void *value)
if (!lykey)
return -1;
+ pthread_mutex_lock(&client->lock);
_noti = g_hash_table_lookup(client->noti_cbs, lykey);
free(lykey);
*noti = _noti;
+ pthread_mutex_unlock(&client->lock);
return 0;
}
return -1;
}
- pthread_mutex_lock(¬i_cbs_lock);
+ pthread_mutex_lock(¬i->cbs_lock);
for (l = noti->callbacks; l; l = g_list_next(l)) {
struct bxt_noti_cb *noticb = l->data;
continue;
assert(noticb->callback);
- pthread_mutex_unlock(¬i_cbs_lock);
+ pthread_mutex_unlock(¬i->cbs_lock);
noticb->callback(rqst.layer, rqst.key, rqst.val, noticb->data);
- pthread_mutex_lock(¬i_cbs_lock);
+ pthread_mutex_lock(¬i->cbs_lock);
}
- pthread_mutex_unlock(¬i_cbs_lock);
+ pthread_mutex_unlock(¬i->cbs_lock);
free_request(&rqst);
return 0;
if (!lykey)
return -1;
+ pthread_mutex_lock(&client->lock);
_noti = g_hash_table_lookup(client->noti_cbs, lykey);
if (_noti) {
free(lykey);
*noti = _noti;
+ pthread_mutex_unlock(&client->lock);
return 0;
}
_noti = calloc(1, sizeof(*_noti));
if (!_noti) {
free(lykey);
+ pthread_mutex_unlock(&client->lock);
return -1;
}
_noti->layer_key = lykey;
+ pthread_mutex_init(&_noti->cbs_lock, NULL);
g_hash_table_insert(client->noti_cbs, lykey, _noti);
*noti = _noti;
+ pthread_mutex_unlock(&client->lock);
return 0;
}
assert(noti);
assert(notify);
- pthread_mutex_lock(¬i_cbs_lock);
+ pthread_mutex_lock(¬i->cbs_lock);
for (l = noti->callbacks; l; l = g_list_next(l)) {
noticb = l->data;
if (noticb->callback == notify) {
if (noticb->deleted == FALSE) {
errno = EEXIST;
- pthread_mutex_unlock(¬i_cbs_lock);
+ pthread_mutex_unlock(¬i->cbs_lock);
return -1;
}
noticb->callback = notify;
noticb->data = notify_data;
- pthread_mutex_unlock(¬i_cbs_lock);
+ pthread_mutex_unlock(¬i->cbs_lock);
return 0;
}
}
noticb = calloc(1, sizeof(*noticb));
if (!noticb) {
- pthread_mutex_unlock(¬i_cbs_lock);
+ pthread_mutex_unlock(¬i->cbs_lock);
return -1;
}
noti->callbacks = g_list_append(noti->callbacks, noticb);
- pthread_mutex_unlock(¬i_cbs_lock);
+ pthread_mutex_unlock(¬i->cbs_lock);
return 0;
}
if (!lykey)
return;
+ pthread_mutex_lock(&client->lock);
g_hash_table_remove(client->noti_cbs, lykey);
+ pthread_mutex_unlock(&client->lock);
free(lykey);
}
return -1;
}
+ pthread_mutex_lock(&client->lock);
req = g_hash_table_lookup(client->req_cbs,
GUINT_TO_POINTER(resp.msgid));
+ pthread_mutex_unlock(&client->lock);
if (!req) {
bxt_err("proc msg: msgid %d not exist", resp.msgid);
free_response(&resp);
free_response(&resp);
+ pthread_mutex_lock(&client->lock);
g_hash_table_remove(client->req_cbs, GUINT_TO_POINTER(resp.msgid));
+ pthread_mutex_unlock(&client->lock);
return 0;
}
/* poll or proc error */
if (r == -1) {
+ pthread_mutex_lock(&client->lock);
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(msgid));
+ pthread_mutex_unlock(&client->lock);
return -1;
}
+ pthread_mutex_lock(&client->lock);
req = g_hash_table_lookup(client->req_cbs,
GUINT_TO_POINTER(msgid));
/* req is processed */
- if (!req)
+ if (!req) {
+ pthread_mutex_unlock(&client->lock);
return 0;
+ }
+ pthread_mutex_unlock(&client->lock);
clock_gettime(CLOCK_MONOTONIC, &t);
ms = TS_SUB(&to, &t);
}
bxt_err("wait response: timeout");
errno = ETIMEDOUT;
+ pthread_mutex_lock(&client->lock);
g_hash_table_remove(client->req_cbs, GUINT_TO_POINTER(msgid));
+ pthread_mutex_unlock(&client->lock);
return -1;
}
rqst.key = (char *)key;
rqst.val = (struct buxton_value *)val;
+ pthread_mutex_lock(&client->lock);
g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
r = send_req(client, &rqst);
if (r == -1) {
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(req->msgid));
+ pthread_mutex_unlock(&client->lock);
return NULL;
}
+ pthread_mutex_unlock(&client->lock);
return req;
}
rqst.layer = req->layer;
rqst.key = (char *)key;
+ pthread_mutex_lock(&client->lock);
g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
r = send_req(client, &rqst);
if (r == -1) {
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(req->msgid));
+ pthread_mutex_unlock(&client->lock);
return NULL;
}
+ pthread_mutex_unlock(&client->lock);
return req;
}
rqst.msgid = req->msgid;
rqst.layer = req->layer;
+ pthread_mutex_lock(&client->lock);
g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
r = send_req(client, &rqst);
if (r == -1) {
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(req->msgid));
+ pthread_mutex_unlock(&client->lock);
return NULL;
}
+ pthread_mutex_unlock(&client->lock);
return req;
}
rqst.layer = req->layer;
rqst.key = (char *)key;
+ pthread_mutex_lock(&client->lock);
g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
r = send_req(client, &rqst);
if (r == -1) {
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(req->msgid));
+ pthread_mutex_unlock(&client->lock);
return NULL;
}
+ pthread_mutex_unlock(&client->lock);
return req;
}
assert(noti);
- pthread_mutex_lock(¬i_cbs_lock);
+ pthread_mutex_lock(¬i->cbs_lock);
for (l = noti->callbacks, ll = g_list_next(l); l;
l = ll, ll = g_list_next(ll)) {
noticb = l->data;
free(noticb);
}
}
- pthread_mutex_unlock(¬i_cbs_lock);
+ pthread_mutex_unlock(¬i->cbs_lock);
noti->id = 0;
cnt = 0;
f = FALSE;
- pthread_mutex_lock(¬i_cbs_lock);
+ pthread_mutex_lock(¬i->cbs_lock);
for (l = noti->callbacks; l; l = g_list_next(l)) {
struct bxt_noti_cb *noticb = l->data;
if (noticb->deleted == FALSE)
cnt++;
}
- pthread_mutex_unlock(¬i_cbs_lock);
+ pthread_mutex_unlock(¬i->cbs_lock);
if (!f) {
errno = ENOENT;
rqst.layer = req->layer;
rqst.key = (char *)key;
+ pthread_mutex_lock(&client->lock);
g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
r = send_req(client, &rqst);
if (r == -1) {
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(req->msgid));
+ pthread_mutex_unlock(&client->lock);
return NULL;
}
+ pthread_mutex_unlock(&client->lock);
return req;
}
rqst.wpriv = (char *)write_privilege;
rqst.val = (struct buxton_value *)val;
+ pthread_mutex_lock(&client->lock);
g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
r = send_req(client, &rqst);
if (r == -1) {
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(req->msgid));
+ pthread_mutex_unlock(&client->lock);
return NULL;
}
+ pthread_mutex_unlock(&client->lock);
return req;
}
rqst.layer = req->layer;
rqst.key = (char *)key;
+ pthread_mutex_lock(&client->lock);
g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
r = send_req(client, &rqst);
if (r == -1) {
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(req->msgid));
+ pthread_mutex_lock(&client->lock);
return NULL;
}
+ pthread_mutex_unlock(&client->lock);
return req;
}
val.type = BUXTON_TYPE_PRIVILEGE;
val.value.s = (char *)privilege;
+ pthread_mutex_lock(&client->lock);
g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
r = send_req(client, &rqst);
if (r == -1) {
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(req->msgid));
+ pthread_mutex_unlock(&client->lock);
return NULL;
}
+ pthread_mutex_unlock(&client->lock);
return req;
}
rqst.layer = req->layer;
rqst.key = (char *)key;
+ pthread_mutex_lock(&client->lock);
g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
r = send_req(client, &rqst);
if (r == -1) {
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(req->msgid));
+ pthread_mutex_unlock(&client->lock);
return NULL;
}
+ pthread_mutex_unlock(&client->lock);
return req;
}
val.type = BUXTON_TYPE_BOOLEAN;
val.value.b = enable;
+ pthread_mutex_lock(&client->lock);
g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
r = send_req(client, &rqst);
if (r == -1) {
g_hash_table_remove(client->req_cbs,
GUINT_TO_POINTER(req->msgid));
+ pthread_mutex_unlock(&client->lock);
return NULL;
}
+ pthread_mutex_unlock(&client->lock);
return req;
}
if (!noti)
return;
- pthread_mutex_lock(¬i_cbs_lock);
+ pthread_mutex_lock(¬i->cbs_lock);
g_list_free_full(noti->callbacks, (GDestroyNotify)free);
- pthread_mutex_unlock(¬i_cbs_lock);
+ pthread_mutex_unlock(¬i->cbs_lock);
if (noti->id) {
g_source_remove(noti->id);
pthread_mutex_lock(&clients_lock);
clients = g_list_remove(clients, cli);
+ pthread_mutex_lock(&cli->lock);
if (cli->req_cbs)
g_hash_table_destroy(cli->req_cbs);
if (cli->noti_cbs)
g_hash_table_destroy(cli->noti_cbs);
+ pthread_mutex_unlock(&cli->lock);
free(cli);
pthread_mutex_unlock(&clients_lock);
cli->st_callback = callback;
cli->st_data = user_data;
+ pthread_mutex_init(&cli->lock, NULL);
+ pthread_mutex_lock(&cli->lock);
cli->req_cbs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify)free_req);
if (!cli->req_cbs) {
free_client(cli);
errno = ENOMEM;
+ pthread_mutex_unlock(&cli->lock);
return -1;
}
-
cli->noti_cbs = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, (GDestroyNotify)free_noti);
if (!cli->noti_cbs) {
free_client(cli);
errno = ENOMEM;
+ pthread_mutex_unlock(&cli->lock);
return -1;
}
+ pthread_mutex_unlock(&cli->lock);
cli->fd = connect_server(SOCKPATH);
if (cli->fd == -1) {