uint32_t _notify_lib_resume(notify_state_t *ns, pid_t pid, int token) { client_t *c; uint64_t cid; uint32_t status = NOTIFY_STATUS_OK; if (ns == NULL) return NOTIFY_STATUS_FAILED; cid = make_client_id(pid, token); if (ns->lock != NULL) pthread_mutex_lock(ns->lock); c = _nc_table_find_64(ns->client_table, cid); if (c != NULL) { if (c->suspend_count > 0) c->suspend_count--; if (c->suspend_count == 0) { c->state &= ~NOTIFY_CLIENT_STATE_SUSPENDED; c->state &= ~NOTIFY_CLIENT_STATE_TIMEOUT; if (c->state & NOTIFY_CLIENT_STATE_PENDING) { status = _internal_send(ns, c); } } } if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return status; }
/* * Set state value for a name. */ uint32_t _notify_lib_set_state(notify_state_t *ns, uint64_t nid, uint64_t state, uid_t uid, gid_t gid) { name_info_t *n; int auth; if (ns == NULL) return NOTIFY_STATUS_FAILED; if (ns->lock != NULL) pthread_mutex_lock(ns->lock); n = (name_info_t *)_nc_table_find_64(ns->name_id_table, nid); if (n == NULL) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_INVALID_NAME; } auth = _internal_check_access(ns, n->name, uid, gid, NOTIFY_ACCESS_WRITE); if (auth != 0) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_NOT_AUTHORIZED; } n->state = state; n->state_time = mach_absolute_time(); if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_OK; }
/* * Get state value for a name. */ uint32_t _notify_lib_get_state(notify_state_t *ns, uint64_t nid, uint64_t *state, uid_t uid, gid_t gid) { name_info_t *n; if (ns == NULL) return NOTIFY_STATUS_FAILED; if (state == NULL) return NOTIFY_STATUS_FAILED; *state = 0; if (ns->lock != NULL) pthread_mutex_lock(ns->lock); n = (name_info_t *)_nc_table_find_64(ns->name_id_table, nid); if (n == NULL) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_INVALID_NAME; } #ifdef GET_STATE_AUTH_CHECK int auth = _internal_check_access(ns, n->name, uid, gid, NOTIFY_ACCESS_READ); if (auth != 0) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_NOT_AUTHORIZED; } #endif *state = n->state; if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_OK; }
int * _notify_lib_check_addr(notify_state_t *ns, pid_t pid, int token) { client_t *c; int *addr; uint64_t cid; if (ns == NULL) return NULL; cid = make_client_id(pid, token); if (ns->lock != NULL) pthread_mutex_lock(ns->lock); c = _nc_table_find_64(ns->client_table, cid); if (c == NULL) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NULL; } if (c->name_info == NULL) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NULL; } addr = (int *)&(c->name_info->val); if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return addr; }
/* * SPI: get value for a name. */ uint32_t _notify_lib_peek(notify_state_t *ns, pid_t pid, int token, int *val) { client_t *c; uint64_t cid; if (ns == NULL) return NOTIFY_STATUS_FAILED; if (val == NULL) return NOTIFY_STATUS_FAILED; cid = make_client_id(pid, token); if (ns->lock != NULL) pthread_mutex_lock(ns->lock); c = _nc_table_find_64(ns->client_table, cid); if (c == NULL) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_INVALID_TOKEN; } if (c->name_info == NULL) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_INVALID_TOKEN; } *val = c->name_info->val; if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_OK; }
void _notify_lib_suspend(notify_state_t *ns, pid_t pid, int token) { client_t *c; uint64_t cid; if (ns == NULL) return; cid = make_client_id(pid, token); if (ns->lock != NULL) pthread_mutex_lock(ns->lock); c = _nc_table_find_64(ns->client_table, cid); if (c != NULL) { c->state |= NOTIFY_CLIENT_STATE_SUSPENDED; if (c->suspend_count < UINT32_MAX) c->suspend_count++; } if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); }
/* * Cancel (delete) a client */ static void _internal_cancel(notify_state_t *ns, uint64_t cid) { client_t *c; name_info_t *n; if (ns == NULL) return; c = NULL; n = NULL; c = _nc_table_find_64(ns->client_table, cid); if (c == NULL) return; n = c->name_info; if (n == NULL) return; _nc_table_delete_64(n->subscription_table, cid); _internal_client_release(ns, c); _internal_release_name_info(ns, n); }
uint32_t _notify_lib_post_nid(notify_state_t *ns, uint64_t nid, uid_t uid, gid_t gid) { name_info_t *n; uint32_t status; if (ns == NULL) return NOTIFY_STATUS_FAILED; if (ns->lock != NULL) pthread_mutex_lock(ns->lock); n = (name_info_t *)_nc_table_find_64(ns->name_id_table, nid); if (n == NULL) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_INVALID_NAME; } status = _internal_post_name(ns, n, uid, gid); if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return status; }
/* * Set value for a name. */ uint32_t _notify_lib_set_val(notify_state_t *ns, pid_t pid, int token, int val, uid_t uid, gid_t gid) { client_t *c; int auth; uint64_t cid; if (ns == NULL) return NOTIFY_STATUS_FAILED; cid = make_client_id(pid, token); if (ns->lock != NULL) pthread_mutex_lock(ns->lock); c = _nc_table_find_64(ns->client_table, cid); if (c == NULL) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_INVALID_TOKEN; } if (c->name_info == NULL) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_INVALID_TOKEN; } auth = _internal_check_access(ns, c->name_info->name, uid, gid, NOTIFY_ACCESS_WRITE); if (auth != 0) { if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_NOT_AUTHORIZED; } c->name_info->val = val; if (ns->lock != NULL) pthread_mutex_unlock(ns->lock); return NOTIFY_STATUS_OK; }
static client_t * _internal_client_new(notify_state_t *ns, pid_t pid, int token) { client_t *c; uint64_t cid = make_client_id(pid, token); if (ns == NULL) return NULL; /* detect duplicates - should never happen, but it would be bad */ c = _nc_table_find_64(ns->client_table, cid); if (c != NULL) return NULL; c = calloc(1, sizeof(client_t)); if (c == NULL) return NULL; c->client_id = cid; c->pid = pid; c->send_val = token; _nc_table_insert_64(ns->client_table, cid, c); return c; }
void * _nc_table_find_n(table_t *tin, uint32_t key) { uint64_t n64 = key; return _nc_table_find_64(tin, n64); }