mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
remove the limit of global queue size
This commit is contained in:
@@ -12,6 +12,7 @@ Dev version
|
|||||||
* Remove skynet.blockcall , simplify the implement of message queue.
|
* Remove skynet.blockcall , simplify the implement of message queue.
|
||||||
* When dropping message queue (at service exit) , dispatcher will post an error back to the source of each message.
|
* When dropping message queue (at service exit) , dispatcher will post an error back to the source of each message.
|
||||||
* Remove skynet.watch , monitor is not necessary for watching skynet.call . so simplemonitor.lua is move to examples.
|
* Remove skynet.watch , monitor is not necessary for watching skynet.call . so simplemonitor.lua is move to examples.
|
||||||
|
* Remove the limit of global queue size (64K actived service limit before).
|
||||||
|
|
||||||
v0.1.1 (2014-4-28)
|
v0.1.1 (2014-4-28)
|
||||||
------------------
|
------------------
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ struct message_queue {
|
|||||||
int release;
|
int release;
|
||||||
int in_global;
|
int in_global;
|
||||||
struct skynet_message *queue;
|
struct skynet_message *queue;
|
||||||
|
struct message_queue *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct global_queue {
|
struct global_queue {
|
||||||
@@ -34,7 +35,7 @@ struct global_queue {
|
|||||||
// We use a separated flag array to ensure the mq is pushed.
|
// We use a separated flag array to ensure the mq is pushed.
|
||||||
// See the comments below.
|
// See the comments below.
|
||||||
bool * flag;
|
bool * flag;
|
||||||
|
struct message_queue *list;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct global_queue *Q = NULL;
|
static struct global_queue *Q = NULL;
|
||||||
@@ -48,6 +49,18 @@ static void
|
|||||||
skynet_globalmq_push(struct message_queue * queue) {
|
skynet_globalmq_push(struct message_queue * queue) {
|
||||||
struct global_queue *q= Q;
|
struct global_queue *q= Q;
|
||||||
|
|
||||||
|
if (q->flag[GP(q->tail)]) {
|
||||||
|
// The queue may full seldom, save queue in list
|
||||||
|
assert(queue->next == NULL);
|
||||||
|
struct message_queue * last;
|
||||||
|
do {
|
||||||
|
last = q->list;
|
||||||
|
queue->next = last;
|
||||||
|
} while(!__sync_bool_compare_and_swap(&q->list, last, queue));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t tail = GP(__sync_fetch_and_add(&q->tail,1));
|
uint32_t tail = GP(__sync_fetch_and_add(&q->tail,1));
|
||||||
// The thread would suspend here, and the q->queue[tail] is last version ,
|
// The thread would suspend here, and the q->queue[tail] is last version ,
|
||||||
// but the queue tail is increased.
|
// but the queue tail is increased.
|
||||||
@@ -61,11 +74,25 @@ struct message_queue *
|
|||||||
skynet_globalmq_pop() {
|
skynet_globalmq_pop() {
|
||||||
struct global_queue *q = Q;
|
struct global_queue *q = Q;
|
||||||
uint32_t head = q->head;
|
uint32_t head = q->head;
|
||||||
uint32_t head_ptr = GP(head);
|
|
||||||
if (head_ptr == GP(q->tail)) {
|
if (head == q->tail) {
|
||||||
|
// The queue is empty.
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t head_ptr = GP(head);
|
||||||
|
|
||||||
|
struct message_queue * list = q->list;
|
||||||
|
if (list) {
|
||||||
|
// If q->list is not empty, try to load it back to the queue
|
||||||
|
struct message_queue *newhead = list->next;
|
||||||
|
if (__sync_bool_compare_and_swap(&q->list, list, newhead)) {
|
||||||
|
// try load list only once, if success , push it back to the queue.
|
||||||
|
list->next = NULL;
|
||||||
|
skynet_globalmq_push(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check the flag first, if the flag is false, the pushing may not complete.
|
// Check the flag first, if the flag is false, the pushing may not complete.
|
||||||
if(!q->flag[head_ptr]) {
|
if(!q->flag[head_ptr]) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -96,12 +123,14 @@ skynet_mq_create(uint32_t handle) {
|
|||||||
q->in_global = MQ_IN_GLOBAL;
|
q->in_global = MQ_IN_GLOBAL;
|
||||||
q->release = 0;
|
q->release = 0;
|
||||||
q->queue = skynet_malloc(sizeof(struct skynet_message) * q->cap);
|
q->queue = skynet_malloc(sizeof(struct skynet_message) * q->cap);
|
||||||
|
q->next = NULL;
|
||||||
|
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_release(struct message_queue *q) {
|
_release(struct message_queue *q) {
|
||||||
|
assert(q->next == NULL);
|
||||||
skynet_free(q->queue);
|
skynet_free(q->queue);
|
||||||
skynet_free(q);
|
skynet_free(q);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user