static inline void rwlock_rlock(struct rwlock *lock) { for (;;) { while(lock->write) { atom_sync(); } atom_inc(&lock->read); if (lock->write) { atom_dec(&lock->read); } else { break; } } }
void * index_grab(struct index *idx, id_t id) { struct slot *slot; void *ud; if (id == 0) return 0; rwlock_rlock(&idx->lock); slot = &idx->slot[HASH(id)]; if (slot->id != id) { rwlock_runlock(&idx->lock); return 0; } atom_inc(&slot->ref); ud = slot->ud; rwlock_runlock(&idx->lock); return ud; }
void * handlemap_grab(struct handlemap *m, handleid id) { struct handleslot * slot; void * ud; if (id == 0) return NULL; rwlock_rlock(&m->lock); slot = &m->slot[id & (m->cap - 1)]; if (slot->id != id) { rwlock_runlock(&m->lock); return NULL; } atom_inc(&slot->ref); ud = slot->ud; rwlock_runlock(&m->lock); return ud; }
static int socket_next_id(void) { int i; for (i = 0; i < MAX_SOCKET; i++) { struct socket *sock; int id = atom_inc(&(S.next_id)); if (id < 0) { id = atom_and(&(S.next_id), 0x7fffffff); } sock = &S.slot[HASH_ID(id)]; if (sock->type == SOCKET_TYPE_INVALID) { if (atom_cas(&(sock->type), SOCKET_TYPE_INVALID, SOCKET_TYPE_RESERVE)) { sock->id = id; sock->fd = -1; return id; } --i; } } return -1; }
struct skynet_service * skynet_service_grab(address_t id) { if (id == 0) return NULL; struct service_node *sn = &G->s[id % MAX_SERVICE]; if (sn->exit || sn->id != id) return NULL; atom_inc(&sn->ref); if (sn->exit) { // double check, service may exit after inc ref // .ref never inc after .exit set atom_dec(&sn->ref); return NULL; } // the ref is great than 1, so .svc is safe now if (skynet_service_id(sn->svc) != id) { atom_dec(&sn->ref); return NULL; } return sn->svc; }
int32_t _bus_terminal_init_attach(bus_terminal_t* bt, int16_t key) { int32_t buskey = (key << 16); int32_t i; struct shm_t* shm; int32_t registered = -1; // attach exsit shm shm = shm_create(buskey, sizeof(bus_t), 1); if (!shm) { return -1; } bt->bus = (bus_t*)shm_mem(shm); // invalid shm data if (bt->bus->key != buskey || bt->bus->size != sizeof(bus_t)) { return -1; } // register terminal info for (i = 0; i < bt->bus->terminal_count; ++ i) { if (bt->bus->terminals[i] == bt->self) { registered = 0; break; } } if (registered != 0) { if (bt->bus->terminal_count >= BUS_MAX_TERMINAL_COUNT) { return -1; } else { bt->bus->terminals[bt->bus->terminal_count ++] = bt->self; atom_inc(&bt->bus->terminal_version); } } return 0; }
int32_t _bus_terminal_register_channel(bus_terminal_t* bt, bus_addr_t to, size_t sz) { int i, found, ret; struct bus_channel_t* bc; struct bus_terminal_channel_t* btc; if (!bt) return bus_err_fail; // make sure same version bus_terminal_tick(bt); // add lock process_lock_lock(bt->lock); if (bt->local_channel_version != bt->bus->channel_version) { process_lock_unlock(bt->lock); return bus_err_fail; } // no left free channel if (bt->bus->channel_count >= BUS_MAX_CHANNLE_COUNT) { process_lock_unlock(bt->lock); return bus_err_channel_full; } // check terminals found = -1; for (i = 0; i < bt->bus->terminal_count; ++ i) { if (bt->bus->terminals[i] == to) { found = 0; break; } } if (found) { process_lock_unlock(bt->lock); return bus_err_peek_fail; } // check not self (no loop bus) if (to == bt->self) { process_lock_unlock(bt->lock); return bus_err_peek_fail; } // create channel bc = &bt->bus->channels[bt->bus->channel_count]; bc->from = bt->self; bc->to = to; bc->shmkey = bt->bus->key + (++ bt->bus->channel_key); bc->channel_size = sz; btc = bus_terminal_channel_init(bc->shmkey, bc->from, bc->to, bc->channel_size, 0); if (!btc) { process_lock_unlock(bt->lock); return bus_err_channel_fail; } // add terminal-channel to idtable ret = idtable_add(bt->send_channels, bc->to, btc); assert(0 == ret); // add channel version ++ bt->bus->channel_count; atom_inc(&bt->bus->channel_version); process_lock_unlock(bt->lock); bt->local_channel_version = bt->bus->channel_version; return bus_ok; }
void skynet_message_grab(struct skynet_message *msg) { assert(msg->ref > 0); atom_inc(&msg->ref); }
void retain() { atom_inc(&ref_); }
static inline void service_total_inc(void) { atom_inc(&g.total); }
void monitor_trigger(struct monitor *monitor, uint32_t source, uint32_t handle) { monitor->source = source; monitor->handle = handle; atom_inc(&monitor->version); }