예제 #1
0
파일: index.c 프로젝트: zhoukk/service
void *
index_release(struct index *idx, id_t id) {
  struct slot *slot;
  void *ud = 0;
  if (id == 0) return 0;
  rwlock_rlock(&idx->lock);
  slot = &idx->slot[HASH(id)];
  if (slot->id != id) {
    rwlock_runlock(&idx->lock);
    return 0;
  }
  if (atom_dec(&slot->ref) <= 0) ud = slot->ud;
  rwlock_runlock(&idx->lock);

  if (ud > 0) {
    rwlock_wlock(&idx->lock);
    slot = &idx->slot[HASH(id)];
    if (slot->id != id) {
      rwlock_wunlock(&idx->lock);
      return 0;
    }
    if (slot->ref > 0) {
      rwlock_wunlock(&idx->lock);
      return 0;
    }
    ud = slot->ud;
    slot->id = 0;
    --idx->cnt;
    rwlock_wunlock(&idx->lock);
    return ud;
  }
  return 0;
}
예제 #2
0
파일: lua-stm.c 프로젝트: 109383670/skynet
static void
stm_grab(struct stm_object *obj) {
	rwlock_rlock(&obj->lock);
	int ref = __sync_fetch_and_add(&obj->reference,1);
	rwlock_runlock(&obj->lock);
	assert(ref > 0);
}
예제 #3
0
uint32_t 
skynet_handle_findname(const char * name) {
	struct handle_storage *s = H;

	rwlock_rlock(&s->lock);

	uint32_t handle = 0;

	int begin = 0;
	int end = s->name_count - 1;
	while (begin<=end) {
		int mid = (begin+end)/2;
		struct handle_name *n = &s->name[mid];
		int c = strcmp(n->name, name);
		if (c==0) {
			handle = n->handle;
			break;
		}
		if (c<0) {
			begin = mid + 1;
		} else {
			end = mid - 1;
		}
	}

	rwlock_runlock(&s->lock);

	return handle;
}
예제 #4
0
파일: index.c 프로젝트: zhoukk/service
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;
}
예제 #5
0
uint32_t 
skynet_handle_findname(const char * name) {
	struct handle_storage *s = H;

	rwlock_rlock(&s->lock);

	uint32_t handle = 0;

	// 从头到位遍历搜索
	int begin = 0;
	int end = s->name_count - 1;
	while (begin<=end) {

		// 折半查询, 必须保证查询的序列是已经排序好的.
		int mid = (begin+end)/2;
		struct handle_name *n = &s->name[mid];
		int c = strcmp(n->name, name);
		if (c==0) {
			handle = n->handle;
			break;
		}

		// 关键的就在这里了, 决定往那个方向查询
		if (c<0) {
			begin = mid + 1;
		} else {
			end = mid - 1;
		}
	}

	rwlock_runlock(&s->lock);

	return handle;
}
예제 #6
0
static void
stm_grab(struct stm_object *obj) {
	rwlock_rlock(&obj->lock);
	int ref = ATOM_FINC(&obj->reference);
	rwlock_runlock(&obj->lock);
	assert(ref > 0);
}
예제 #7
0
void 
skynet_handle_retireall() {
	struct handle_storage *s = H;
	for (;;) {	// 保证所有的资源都被回收

		int n = 0;
		int i;
		for (i = 0; i < s->slot_size; i++) {
			// 保证线程安全
			rwlock_rlock(&s->lock);

			// 拿到 context 的 handle
			struct skynet_context * ctx = s->slot[i];
			uint32_t handle = 0;
			if (ctx)
				handle = skynet_context_handle(ctx);

			rwlock_runlock(&s->lock);

			// 对 handle 做回收处理
			if (handle != 0) {		// 这就是上面说的, handle 不会使用 0.
				if (skynet_handle_retire(handle)) {
					++n;
				}
			}
		}

		// 保证全部的 context 全部删除
		if (n==0)
			return;
	}
}
예제 #8
0
// 根据名称查找handle
uint32_t 
skynet_handle_findname(const char * name) {
	struct handle_storage *s = H;

	rwlock_rlock(&s->lock);

	uint32_t handle = 0;

	int begin = 0;
	int end = s->name_count - 1;
	while (begin<=end) {
		int mid = (begin+end)/2; // 这里用的二分查找 听说会有整形溢出 改成减法可以避免 不清楚具体怎么搞
		struct handle_name *n = &s->name[mid];
		int c = strcmp(n->name, name); // // 一直在头部插入 实际上这样插入后 name 会按长度大小排好序 这样就能使用二分查找了
		if (c==0) {
			handle = n->handle;
			break;
		}
		if (c<0) {
			begin = mid + 1;
		} else {
			end = mid - 1;
		}
	}

	rwlock_runlock(&s->lock);

	return handle;
}
예제 #9
0
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;
}
예제 #10
0
static void *
release_ref(struct handlemap *m, handleid id) {
	struct handleslot * slot;
	void * ud = NULL;
	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;
	}
	if (atom_dec(&slot->ref) <= 0) {
		ud = slot->ud;
	}
	rwlock_runlock(&m->lock);
	return ud;
}
예제 #11
0
static void
stm_releasereader(struct stm_object *obj) {
	rwlock_rlock(&obj->lock);
	if (ATOM_DEC(&obj->reference) == 0) {
		// last reader, no writer. so no need to unlock
		assert(obj->copy == NULL);
		skynet_free(obj);
		return;
	}
	rwlock_runlock(&obj->lock);
}
예제 #12
0
static struct stm_copy *
stm_copy(struct stm_object *obj) {
	rwlock_rlock(&obj->lock);
	struct stm_copy * ret = obj->copy;
	if (ret) {
		int ref = ATOM_FINC(&ret->reference);
		assert(ref > 0);
	}
	rwlock_runlock(&obj->lock);
	
	return ret;
}
예제 #13
0
파일: lua-stm.c 프로젝트: 109383670/skynet
static struct stm_copy *
stm_copy(struct stm_object *obj) {
	rwlock_rlock(&obj->lock);
	struct stm_copy * ret = obj->copy;
	if (ret) {
		int ref = __sync_fetch_and_add(&ret->reference,1);
		assert(ref > 0);
	}
	rwlock_runlock(&obj->lock);
	
	return ret;
}
예제 #14
0
int
skynet_mq_popmt(struct skynet_mq *mq, struct skynet_message_package *pack) {
	if (mq->head == mq->tail) {
		return 0;
	}
	rwlock_rlock(&mq->lock);
		// only one reader, so use read lock is ok.
		// but we can call skynet_mq_pushmt in another thread
		*pack = mq->q[mq->head];
		pop_message(mq);
	rwlock_runlock(&mq->lock);
	return 1;
}
예제 #15
0
파일: index.c 프로젝트: zhoukk/service
int
index_list(struct index *idx, int n, id_t *list) {
  int i, cnt = 0;
  rwlock_rlock(&idx->lock);
  if (list) {
    for (i = 0; cnt < n && i < idx->cap; i++) {
      struct slot *slot = &idx->slot[i];
      if (slot->id == 0) continue;
      list[cnt] = slot->id;
      ++cnt;
    }
  }
  cnt = idx->cnt;
  rwlock_runlock(&idx->lock);
  return cnt;
}
예제 #16
0
int
handlemap_list(struct handlemap *m, int n, handleid * result) {
	int i,t=0;
	rwlock_rlock(&m->lock);
	for (i=0;t < n && i<m->cap;i++) {
		struct handleslot *slot = &m->slot[i];
		if (slot->id == 0)
			continue;
		result[t] = slot->id;
		++t;
	}

	t=m->n;
	rwlock_runlock(&m->lock);
	return t;
}
예제 #17
0
// 通过handle获取skynet_context, skynet_context的引用计数加1
struct skynet_context * 
skynet_handle_grab(uint32_t handle) {
	struct handle_storage *s = H;
	struct skynet_context * result = NULL;

	rwlock_rlock(&s->lock);

	uint32_t hash = handle & (s->slot_size-1);
	struct skynet_context * ctx = s->slot[hash];
	if (ctx && skynet_context_handle(ctx) == handle) {
		result = ctx;
		skynet_context_grab(result); // 	__sync_add_and_fetch(&ctx->ref,1);	skynet_context引用计数加1
	}

	rwlock_runlock(&s->lock);

	return result;
}
예제 #18
0
void 
skynet_handle_retireall() {
	struct handle_storage *s = H;
	for (;;) {
		int n=0;
		int i;
		for (i=0;i<s->slot_size;i++) {
			rwlock_rlock(&s->lock);
			struct skynet_context * ctx = s->slot[i];
			rwlock_runlock(&s->lock);
			if (ctx != NULL) {
				++n;
				skynet_handle_retire(skynet_context_handle(ctx));
			}
		}
		if (n==0)
			return;
	}
}
예제 #19
0
struct skynet_context * 
skynet_handle_grab(uint32_t handle) {
	struct handle_storage *s = H;
	struct skynet_context * result = NULL;

	// 保证线程安全
	rwlock_rlock(&s->lock);
	
	uint32_t hash = handle & (s->slot_size - 1);
	struct skynet_context * ctx = s->slot[hash];
	if (ctx 
	// 1. 判断是否在同一个节点
	// 2. 确认 handle 是没有超出 slot_size 的, 因为可能 slot_size = 8, handle = 15, skynet_context_handle(ctx) = 7
	// 3. 其他线程没有修改 ctx
	&& skynet_context_handle(ctx) == handle) {
		result = ctx;
		skynet_context_grab(result);
	}

	rwlock_runlock(&s->lock);

	return result;
}
예제 #20
0
void 
skynet_handle_retireall() {
	struct handle_storage *s = H;
	for (;;) {
		int n=0;
		int i;
		for (i=0;i<s->slot_size;i++) {
			rwlock_rlock(&s->lock);
			struct skynet_context * ctx = s->slot[i];
			uint32_t handle = 0;
			if (ctx)
				handle = skynet_context_handle(ctx);
			rwlock_runlock(&s->lock);
			if (handle != 0) {
				if (skynet_handle_retire(handle)) {
					++n;
				}
			}
		}
		if (n==0)
			return;
	}
}