swoole_process原始碼分析之push佇列
阿新 • • 發佈:2018-12-13
前面我們分析過了佇列的建立過程,這裡我們看下佇列的push流程,其push呼叫形式如下。
bool swoole_process->push(string $data);
下面我們看下底層實現。
static PHP_METHOD(swoole_process, push) { char *data; zend_size_t length; struct { long type; char data[SW_MSGMAX]; } message; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &length) == FAILURE) { RETURN_FALSE; } if (length <= 0) { swoole_php_fatal_error(E_WARNING, "the data to push is empty."); RETURN_FALSE; } else if (length >= sizeof(message.data)) { swoole_php_fatal_error(E_WARNING, "the data to push is too big."); RETURN_FALSE; } swWorker *process = swoole_get_object(getThis()); if (!process->queue) { swoole_php_fatal_error(E_WARNING, "no msgqueue, can not use push()"); RETURN_FALSE; } message.type = process->id; memcpy(message.data, data, length); if (swMsgQueue_push(process->queue, (swQueue_data *)&message, length) < 0) { RETURN_FALSE; } RETURN_TRUE; }
int swMsgQueue_push(swMsgQueue *q, swQueue_data *in, int length) { int ret; while (1) { ret = msgsnd(q->msg_id, in, length, q->flags); if (ret < 0) { SwooleG.error = errno; if (errno == EINTR) { continue; } else if (errno == EAGAIN) { return -1; } else { swSysError("msgsnd(%d, %d, %ld) failed.", q->msg_id, length, in->mtype); return -1; } } else { return ret; } } return 0; }