Exemple #1
0
/**
 * Asynchronous mode we use a large ring buffer to hold the log messages data,
 * the format of log message is:
 * protocol_id(2 bytes) | data
 *
 * Currently, there are two protocols: 1) fetch msg, 2) thread quit
 * log_file_ptr(4/8 bytes) | len(2 bytes) | log message(len bytes)
 */
static
size_t _log_async_write(flog_file_t* f,
                        const char* header, size_t header_len,
                        const char* log, size_t len)
{
    int is_report_truncated = 0;
    if ( len > LOG_MAX_LEN_PER_MSG ) {
        len = LOG_MAX_LEN_PER_MSG;
        is_report_truncated = 1;
    }

    // check pipe buffer whether have enough space
    thread_data_t* th_data = _get_or_create_thdata();
    size_t msg_body_len = header_len + len + 1;
    size_t total_msg_len = sizeof(log_fetch_msg_head_t) + msg_body_len;
    if ( fmbuf_free(th_data->plog_buf) < total_msg_len ) {
        _log_event_notice(FLOG_EVENT_BUFFER_FULL);
        return 0;
    }

    // wrap and push log message
    log_fetch_msg_head_t msg_header;
    msg_header.id = LOG_PTO_FETCH_MSG;
    msg_header.msgh.f = f;
    msg_header.msgh.len = (unsigned short)msg_body_len;
    if ( fmbuf_push(th_data->plog_buf, &msg_header,
                    sizeof(log_fetch_msg_head_t)) ) {
        _log_event_notice(FLOG_EVENT_ERROR_ASYNC_PUSH);
        return 0;
    }

    if( fmbuf_push(th_data->plog_buf, header, header_len) ) {
        _log_event_notice(FLOG_EVENT_ERROR_ASYNC_PUSH);
        return 0;
    }

    if( fmbuf_push(th_data->plog_buf, log, len) ) {
        _log_event_notice(FLOG_EVENT_ERROR_ASYNC_PUSH);
        return 0;
    }

    if( fmbuf_push(th_data->plog_buf, "\n", 1) ) {
        _log_event_notice(FLOG_EVENT_ERROR_ASYNC_PUSH);
        return 0;
    }

    // notice fetcher to write log
    if ( eventfd_write(th_data->efd, 1) ) {
        _log_event_notice(FLOG_EVENT_ERROR_ASYNC_PUSH);
        return 0;
    }

    // this must be reported after async push
    if (is_report_truncated) {
        _log_event_notice(FLOG_EVENT_TRUNCATED);
    }

    return len;
}
Exemple #2
0
static
void _log_async_write_f(flog_file_t* f,
                        const char* header, size_t header_len,
                        const char* fmt, va_list ap)
{
    // check whether have private thread data, if not, create it
    thread_data_t* th_data = _get_or_create_thdata();

    // check the pipe buffer whether have enough space
    size_t max_msg_len = sizeof(log_fetch_msg_head_t) + header_len +
                         LOG_MAX_LEN_PER_MSG + 1;

    size_t total_free = fmbuf_free(th_data->plog_buf);
    if ( total_free < max_msg_len ) {
        _log_event_notice(FLOG_EVENT_BUFFER_FULL);
        return;
    }

    char* head = fmbuf_head(th_data->plog_buf);
    char* tail = fmbuf_tail(th_data->plog_buf);
    size_t tail_free_size = tail < head ? total_free :
                                  fmbuf_tail_free(th_data->plog_buf);

    if ( tail_free_size >= max_msg_len ) {
        // fill log message in mbuf directly
        char* buf = fmbuf_tail(th_data->plog_buf);
        size_t buff_size = _log_fill_async_msg(f, th_data, buf, header,
                                               header_len, fmt, ap);
        fmbuf_tail_seek(th_data->plog_buf, buff_size, FMBUF_SEEK_RIGHT);
    } else {
        // fill log message in tmp buffer
        char* buf = th_data->tmp_buf;
        size_t buff_size = _log_fill_async_msg(f, th_data, buf, header,
                                               header_len, fmt, ap);
        fmbuf_push(th_data->plog_buf, buf, buff_size);
    }

    // notice fetcher to write log
    if ( eventfd_write(th_data->efd, 1) ) {
        _log_event_notice(FLOG_EVENT_ERROR_ASYNC_PUSH);
        return;
    }
}
Exemple #3
0
// return 0 : post sucess
// return 1 : post failed .. queue full
int     fthpool_post_task(fth_task pf, void* arg)
{
    if ( !pf ) return 1;

    th_msg_t tmsg;
    tmsg.ev = TH_TASK;
    tmsg.pf = pf;
    tmsg.arg = arg;

    ++curr_post;
    curr_post = curr_post < max_num ? curr_post : 0;
    thread_data* pdata = pth_pool[curr_post];
    if ( fmbuf_push(pdata->pbuf, &tmsg, sizeof(th_msg_t)) )
        return 1;

    flock_cond_signal(&pdata->cond);

    return 0;
}
Exemple #4
0
// test fmbuf push and pop
void test_mbuf1()
{
    // create a mbuf with size == 0
    {
        fmbuf* pbuf = fmbuf_create(0);
        FCUNIT_ASSERT(pbuf != NULL);
        FCUNIT_ASSERT(0 == fmbuf_size(pbuf));
        FCUNIT_ASSERT(0 == fmbuf_used(pbuf));
        FCUNIT_ASSERT(0 == fmbuf_free(pbuf));
        fmbuf_delete(pbuf);
    }

    fmbuf* pbuf = fmbuf_create(10);
    FCUNIT_ASSERT(pbuf!=NULL);

    char* push_buf[20];
    char* pop_buf[20];

    // push 1 byte data
    {
        int ret = fmbuf_push(pbuf, push_buf, 1);
        FCUNIT_ASSERT(0 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(1 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(0 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(9 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(9 == total_free);
    }

    // push 9 byte data
    {
        int ret = fmbuf_push(pbuf, push_buf, 9);
        FCUNIT_ASSERT(0 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(10 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(0 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(0 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(0 == total_free);
    }

    // continue push 1 byte data when mbuf is full
    {
        int ret = fmbuf_push(pbuf, push_buf, 1);
        FCUNIT_ASSERT(1 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(10 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(0 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(0 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(0 == total_free);
    }

    // clear and seek mbuf and push 5 bytes
    {
        fmbuf_clear(pbuf);
        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(10 == total_free);

        fmbuf_head_seek(pbuf, 4, FMBUF_SEEK_RIGHT);
        fmbuf_tail_seek(pbuf, 6, FMBUF_SEEK_RIGHT);

        int ret = fmbuf_push(pbuf, push_buf, 5);
        FCUNIT_ASSERT(0 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(7 == used);

        total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(3 == total_free);
    }

    // push 4 bytes but the mbuf only have 3 bytes left
    {
        int ret = fmbuf_push(pbuf, push_buf, 4);
        FCUNIT_ASSERT(1 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(7 == used);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(3 == total_free);
    }

    // push 3 bytes the mbuf is full
    {
        int ret = fmbuf_push(pbuf, push_buf, 3);
        FCUNIT_ASSERT(0 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(10 == used);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(0 == total_free);

        ret = fmbuf_push(pbuf, push_buf, 1);
        FCUNIT_ASSERT(1 == ret);
    }

    //---------------mbuf pop-------------------
    //pop 1 bytes
    {
        fmbuf_clear(pbuf);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        int ret = fmbuf_pop(pbuf, pop_buf, 1);
        FCUNIT_ASSERT(1 == ret);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(0 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(0 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(10 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(10 == total_free);
    }

    // push 5 bytes and pop 1 bytes
    {
        int ret = fmbuf_push(pbuf, push_buf, 5);
        FCUNIT_ASSERT(0 == ret);

        ret = fmbuf_pop(pbuf, pop_buf, 1);
        FCUNIT_ASSERT(0 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(4 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(1 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(5 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(6 == total_free);
    }

    // pop 3 bytes and left 1 byte
    {
        int ret = fmbuf_pop(pbuf, pop_buf, 3);
        FCUNIT_ASSERT(0 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(1 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(4 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(5 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(9 == total_free);
    }

    // pop 2 bytes
    {
        int ret = fmbuf_pop(pbuf, pop_buf, 2);
        FCUNIT_ASSERT(1 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(1 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(4 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(5 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(9 == total_free);
    }

    // clear mbuf and seek tail < head
    {
        fmbuf_clear(pbuf);
        fmbuf_head_seek(pbuf, 4, FMBUF_SEEK_RIGHT);
        fmbuf_tail_seek(pbuf, 2, FMBUF_SEEK_RIGHT);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(9 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(4 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(8 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(1 == total_free);
    }

    // total 9 bytes, pop 7 bytes
    {
        int ret = fmbuf_pop(pbuf, pop_buf, 7);
        FCUNIT_ASSERT(0 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(2 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(0 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(8 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(8 == total_free);
    }

    // pop 2 bytes and then the mbuf is empty
    {
        int ret = fmbuf_pop(pbuf, pop_buf, 2);
        FCUNIT_ASSERT(0 == ret);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(0 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(2 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(8 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(10 == total_free);
    }

    {
        fmbuf_clear(pbuf);
        fmbuf_head_seek(pbuf, 4, FMBUF_SEEK_RIGHT);
        fmbuf_tail_seek(pbuf, 6, FMBUF_SEEK_RIGHT);

        int ret = fmbuf_pop(pbuf, NULL, 4);
        FCUNIT_ASSERT(ret == 1);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(2 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(4 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(4 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(8 == total_free);
    }

    // move 2 bytes
    {
        fmbuf_pop(pbuf, NULL, 2);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(0 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(6 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(4 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(10 == total_free);
    }

    // tail < head, tail_use == 5, but pop 6 bytes
    {
        fmbuf_clear(pbuf);
        fmbuf_head_seek(pbuf, 6, FMBUF_SEEK_RIGHT);
        fmbuf_tail_seek(pbuf, 4, FMBUF_SEEK_RIGHT);

        size_t used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(9 == used);

        fmbuf_pop(pbuf, NULL, 6);

        size_t size = fmbuf_size(pbuf);
        FCUNIT_ASSERT(10 == size);

        used = fmbuf_used(pbuf);
        FCUNIT_ASSERT(3 == used);

        size_t head_free = fmbuf_head_free(pbuf);
        FCUNIT_ASSERT(1 == head_free);

        size_t tail_free = fmbuf_tail_free(pbuf);
        FCUNIT_ASSERT(6 == tail_free);

        size_t total_free = fmbuf_free(pbuf);
        FCUNIT_ASSERT(7 == total_free);
    }

    fmbuf_delete(pbuf);
}
Exemple #5
0
// mbuf as a ring-buffer (the tailer location < header location)
void test_mbuf2()
{
    // mbuf: size = 10b, used = 2b
    // realloc it with same size
    {
        fmbuf* mbuf = fmbuf_create(10);
        int ret = fmbuf_push(mbuf, "11", 2);
        FCUNIT_ASSERT(ret == 0);

        fmbuf* new_buf = fmbuf_realloc(mbuf, 10);
        FCUNIT_ASSERT(new_buf == mbuf);
        fmbuf_delete(mbuf);
    }

    // mbuf: size = 10b, used = 9b
    // realloc it with new size = 20b
    // note: left used <= right used and left used <= increased sz
    {
        fmbuf* mbuf = fmbuf_create(10);
        fmbuf_head_seek(mbuf, 4, FMBUF_SEEK_RIGHT);
        fmbuf_tail_seek(mbuf, 2, FMBUF_SEEK_RIGHT);
        FCUNIT_ASSERT(fmbuf_used(mbuf) == 9);

        fmbuf* new_buf = fmbuf_realloc(mbuf, 20);
        FCUNIT_ASSERT(9 == fmbuf_used(new_buf));
        FCUNIT_ASSERT(11 == fmbuf_free(new_buf));
        FCUNIT_ASSERT(20 == fmbuf_size(new_buf));
        FCUNIT_ASSERT(4 == fmbuf_head_free(new_buf));
        FCUNIT_ASSERT(7 == fmbuf_tail_free(new_buf));
        fmbuf_delete(new_buf);
    }

    // mbuf: size = 10b, used = 9b
    // realloc it with new size = 20b
    // note: left used > right used, left used <= increased sz
    {
        fmbuf* mbuf = fmbuf_create(10);
        fmbuf_head_seek(mbuf, 8, FMBUF_SEEK_RIGHT);
        fmbuf_tail_seek(mbuf, 6, FMBUF_SEEK_RIGHT);
        FCUNIT_ASSERT(fmbuf_used(mbuf) == 9);

        fmbuf* new_buf = fmbuf_realloc(mbuf, 20);
        FCUNIT_ASSERT(9 == fmbuf_used(new_buf));
        FCUNIT_ASSERT(11 == fmbuf_free(new_buf));
        FCUNIT_ASSERT(20 == fmbuf_size(new_buf));
        FCUNIT_ASSERT(18 == fmbuf_head_free(new_buf));
        FCUNIT_ASSERT(14 == fmbuf_tail_free(new_buf));
        fmbuf_delete(new_buf);
    }

    // mbuf: size = 10b, used = 9b
    // realloc it with new size = 11b
    // note: left used <= right used, left used > increased sz
    {
        fmbuf* mbuf = fmbuf_create(10);
        fmbuf_head_seek(mbuf, 4, FMBUF_SEEK_RIGHT);
        fmbuf_tail_seek(mbuf, 2, FMBUF_SEEK_RIGHT);
        FCUNIT_ASSERT(fmbuf_used(mbuf) == 9);

        fmbuf* new_buf = fmbuf_realloc(mbuf, 11);
        FCUNIT_ASSERT(9 == fmbuf_used(new_buf));
        FCUNIT_ASSERT(2 == fmbuf_free(new_buf));
        FCUNIT_ASSERT(11 == fmbuf_size(new_buf));
        FCUNIT_ASSERT(5 == fmbuf_head_free(new_buf));
        FCUNIT_ASSERT(9 == fmbuf_tail_free(new_buf));
        fmbuf_delete(new_buf);
    }

    // mbuf: size = 10b, used = 9b
    // realloc it with new size = 11b
    // note: left used > right used, left used > increased sz
    {
        fmbuf* mbuf = fmbuf_create(10);
        fmbuf_head_seek(mbuf, 8, FMBUF_SEEK_RIGHT);
        fmbuf_tail_seek(mbuf, 6, FMBUF_SEEK_RIGHT);
        FCUNIT_ASSERT(fmbuf_used(mbuf) == 9);

        fmbuf* new_buf = fmbuf_realloc(mbuf, 11);
        FCUNIT_ASSERT(9 == fmbuf_used(new_buf));
        FCUNIT_ASSERT(2 == fmbuf_free(new_buf));
        FCUNIT_ASSERT(11 == fmbuf_size(new_buf));
        FCUNIT_ASSERT(9 == fmbuf_head_free(new_buf));
        FCUNIT_ASSERT(5 == fmbuf_tail_free(new_buf));
        fmbuf_delete(new_buf);
    }

    // mbuf: size = 10b, used = 2b
    // realloc it with new size = 5b
    {
        fmbuf* mbuf = fmbuf_create(10);
        fmbuf_head_seek(mbuf, 10, FMBUF_SEEK_RIGHT);
        fmbuf_tail_seek(mbuf, 1, FMBUF_SEEK_RIGHT);
        FCUNIT_ASSERT(fmbuf_used(mbuf) == 2);

        fmbuf* new_buf = fmbuf_realloc(mbuf, 5);
        FCUNIT_ASSERT(2 == fmbuf_used(new_buf));
        FCUNIT_ASSERT(3 == fmbuf_free(new_buf));
        FCUNIT_ASSERT(5 == fmbuf_size(new_buf));
        FCUNIT_ASSERT(5 == fmbuf_head_free(new_buf));
        FCUNIT_ASSERT(4 == fmbuf_tail_free(new_buf));
        fmbuf_delete(new_buf);
    }

    // mbuf: size = 10b, used = 2b
    // realloc it with new size = 1b
    {
        fmbuf* mbuf = fmbuf_create(10);
        fmbuf_head_seek(mbuf, 10, FMBUF_SEEK_RIGHT);
        fmbuf_tail_seek(mbuf, 1, FMBUF_SEEK_RIGHT);
        FCUNIT_ASSERT(fmbuf_used(mbuf) == 2);

        fmbuf* new_buf = fmbuf_realloc(mbuf, 1);
        FCUNIT_ASSERT(2 == fmbuf_used(new_buf));
        FCUNIT_ASSERT(0 == fmbuf_free(new_buf));
        FCUNIT_ASSERT(2 == fmbuf_size(new_buf));
        FCUNIT_ASSERT(2 == fmbuf_head_free(new_buf));
        FCUNIT_ASSERT(1 == fmbuf_tail_free(new_buf));
        fmbuf_delete(new_buf);
    }
}