コード例 #1
0
ファイル: gr_tcp_out.c プロジェクト: charliexp/grocket
void gr_tcp_out_term()
{
    gr_tcp_out_t *  p = (gr_tcp_out_t *)g_ghost_rocket_global.tcp_out;
    if ( NULL != p ) {

        int thread_count = p->threads.thread_count;
        int i;

        gr_threads_close( & p->threads );

        if ( p->polls ) {
            for ( i = 0; i < thread_count; ++ i ) {
                if ( NULL != p->polls[ i ] ) {
#if ! defined( WIN32 ) && ! defined( WIN64 )
                    if ( ! p->tcp_out_disabled ) {
                        gr_poll_destroy( p->polls[ i ] );
                    }
#endif
                    p->polls[ i ] = NULL;
                }
            }

            gr_free( p->polls );
            p->polls = NULL;
        }

        gr_free( p );
        g_ghost_rocket_global.tcp_out = NULL;
    }
}
コード例 #2
0
ファイル: gr_tcp_in.c プロジェクト: charliexp/grocket
void gr_tcp_in_term()
{
    gr_tcp_in_t *  p = (gr_tcp_in_t *)g_ghost_rocket_global.tcp_in;
    if ( NULL != p ) {

        int i;
        int thread_count = p->threads.thread_count;

        gr_threads_close( & p->threads );

        if ( p->polls ) {
            for ( i = 0; i < thread_count; ++ i ) {
                if ( NULL != p->polls[ i ] ) {
                    gr_poll_destroy( p->polls[ i ] );
                    p->polls[ i ] = NULL;
                }
            }

            gr_free( p->polls );
            p->polls = NULL;
        }

        gr_free( p );
        g_ghost_rocket_global.tcp_in = NULL;
    }
}
コード例 #3
0
ファイル: gr_conn.c プロジェクト: charliexp/grocket
gr_udp_req_t * gr_udp_req_alloc(
    int                     buf_max
)
{
    gr_udp_req_t *  req;

    if ( buf_max < 0 ) {
        return NULL;
    }

    req = (gr_udp_req_t *)gr_calloc( 1, sizeof( gr_udp_req_t ) );
    if ( NULL == req ) {
        return NULL;
    }

    // 标记字段,必须为0
    req->entry.is_tcp   = false;
    // 引用计数为1
    //req->entry.refs     = 1;

    req->buf_max = buf_max;
    if ( req->buf_max > 0 ) {
        req->buf = (char *)gr_malloc( req->buf_max );
        if ( NULL == req->buf ) {
            gr_free( req );
            return NULL;
        }
    }

    return req;
}
コード例 #4
0
ファイル: main.c プロジェクト: CharlesGarrocho/MCC
int main(int argc, const char **argv) {

    if (argc < 2) {
        printf("Argumentos Inválidos...\nUtilize: ./a.out <entrada.txt>");
        exit(EXIT_FAILURE);
    }

    const char *endereco = argv[1];
    clock_t start = clock();

    Graph *graph = gr_load(endereco);
    int a[graph->numero_vertices+1];
    int i;
    for(i = 0; i <= graph->numero_vertices; i++){
        a[i] = 0;
    }
    backtrack(a, -1, graph);

    clock_t end = clock();
    double cpuTime = ((double) (end - start)) / CLOCKS_PER_SEC;

    printf("\nTempo total da execucao: %.2f\n", cpuTime);

    gr_free(graph);

    return EXIT_SUCCESS;
}
コード例 #5
0
ファイル: groupmem.c プロジェクト: bfeeny/shadow
/*@null@*/ /*@only@*/struct group *__gr_dup (const struct group *grent)
{
	struct group *gr;
	int i;

	gr = (struct group *) malloc (sizeof *gr);
	if (NULL == gr) {
		return NULL;
	}
	/* The libc might define other fields. They won't be copied. */
	memset (gr, 0, sizeof *gr);
	gr->gr_gid = grent->gr_gid;
	/*@-mustfreeonly@*/
	gr->gr_name = strdup (grent->gr_name);
	/*@=mustfreeonly@*/
	if (NULL == gr->gr_name) {
		gr_free(gr);
		return NULL;
	}
	/*@-mustfreeonly@*/
	gr->gr_passwd = strdup (grent->gr_passwd);
	/*@=mustfreeonly@*/
	if (NULL == gr->gr_passwd) {
		gr_free(gr);
		return NULL;
	}

	for (i = 0; grent->gr_mem[i]; i++);

	/*@-mustfreeonly@*/
	gr->gr_mem = (char **) malloc ((i + 1) * sizeof (char *));
	/*@=mustfreeonly@*/
	if (NULL == gr->gr_mem) {
		gr_free(gr);
		return NULL;
	}
	for (i = 0; grent->gr_mem[i]; i++) {
		gr->gr_mem[i] = strdup (grent->gr_mem[i]);
		if (NULL == gr->gr_mem[i]) {
			gr_free(gr);
			return NULL;
		}
	}
	gr->gr_mem[i] = NULL;

	return gr;
}
コード例 #6
0
ファイル: gr_module.c プロジェクト: xidianwlc/grocket
void gr_module_term()
{
    gr_module_t * module = (gr_module_t *)g_ghost_rocket_global.module;
    if ( NULL != module ) {
        module_unload( module );

        gr_free( module );
        g_ghost_rocket_global.module = NULL;
    }
}
コード例 #7
0
ファイル: gr_conn.c プロジェクト: charliexp/grocket
void gr_tcp_rsp_free(
    gr_tcp_rsp_t *      rsp
)
{
    gr_debug( "gr_tcp_rsp_free %p", rsp );

    assert( NULL != rsp && NULL != rsp->parent );

    rsp->buf_len = 0;
    rsp->buf_max = 0;
    if ( NULL != rsp->buf ) {
        gr_free( rsp->buf );
        rsp->buf = NULL;
    }

    gr_debug( "[fd=%d][cn=%p]free rsp %p, conn %p", rsp->parent->fd, rsp->parent, rsp );

    gr_free( rsp );
}
コード例 #8
0
ファイル: gr_conn.c プロジェクト: charliexp/grocket
void gr_tcp_req_free(
    gr_tcp_req_t *  req,
    bool            is_recycle
)
{
    gr_thread_t *           thread;

    // 为安全起见, 已经在合适的时候把 parent 设成 NULL 了
    assert( NULL != req /*&& NULL != req->parent*/ );

    // 用worker的线程去存放不再需要的请求对象
    if ( is_recycle ) {
        thread = gr_worker_get_thread_by_tcp_conn( req->parent );
    } else {
        thread = NULL;
    }

    req->buf_len = 0;
    req->buf_sent = 0;

    if ( thread ) {
        // 把它放入线程的 free list 里
        req->entry.next = (gr_queue_item_t *)thread->free_tcp_req_list;
        thread->free_tcp_req_list = req;
#ifdef GR_DEBUG_CONN
        gr_info( ">>>>>F [fd=%d][cn=%p]free req %p. to thread %s%d free list",
            req->parent->fd, req->parent, req, thread->name, thread->id );
#endif
    } else {
        req->buf_max = 0;
        if ( NULL != req->buf ) {
            gr_free( req->buf );
            req->buf = NULL;
        }

#ifdef GR_DEBUG_CONN
        gr_info( "====F [fd=%d][cn=%p]free req %p", req->parent->fd, req->parent, req );
#endif

        gr_free( req );
    }
}
コード例 #9
0
ファイル: gr_conn.c プロジェクト: charliexp/grocket
void gr_udp_req_free(
    gr_udp_req_t *          req
)
{
    assert( NULL != req /*&& req->entry.refs > 0*/ );

    //-- req->entry.refs;

    //if ( 0 == req->entry.refs ) {

        req->buf_len = 0;
        req->buf_max = 0;
        if ( NULL != req->buf ) {
            gr_free( req->buf );
            req->buf = NULL;
        }

        gr_free( req );
    //}
}
コード例 #10
0
ファイル: gr_conn.c プロジェクト: charliexp/grocket
void gr_conn_term()
{
    gr_conn_engine_t *  p;
    p = (gr_conn_engine_t *)g_ghost_rocket_global.conn;
    if ( NULL == p ) {
        return ;
    }

    gr_free( p );

    g_ghost_rocket_global.conn = NULL;
}
コード例 #11
0
ファイル: vm_group.c プロジェクト: lightbase/lightbase-unix
VM_HND  gr_end( )
{
   US     I;

   VM_erro = 0;

   for ( I = 0;   I < GR_QTD;   I++ )
   {
      gr_free( &VM_group[ I ] );
   }

   return( 1 );
}
コード例 #12
0
ファイル: gr_poll_bsd.c プロジェクト: charliexp/grocket
void gr_poll_destroy( gr_poll_t * poll )
{
    if ( NULL == poll ) {
        return;
    }

    if ( -1 != poll->kqfd ) {
        gr_debug( "%s close( %d )", poll->name, poll->kqfd );

        close( poll->kqfd );
        poll->kqfd = -1;
    }

    gr_free( poll );
}
コード例 #13
0
ファイル: gr_conn.c プロジェクト: charliexp/grocket
void gr_tcp_req_set_buf(
    gr_tcp_req_t *          req,
    void *                  buf,
    int                     buf_max,
    int                     buf_len
)
{
    if ( req->buf && req->buf != buf ) {
        gr_free( req->buf );
    }

    req->buf       = buf;
    req->buf_max   = buf_max;
    req->buf_len   = buf_len;
    req->buf_sent  = 0;
}
コード例 #14
0
ファイル: gr_conn.c プロジェクト: charliexp/grocket
void gr_tcp_rsp_set_buf(
    gr_tcp_rsp_t *  rsp,
    void *          buf,
    int             buf_max,
    int             buf_len,
    int             sent
)
{
    if ( rsp->buf && rsp->buf != buf ) {
        gr_free( rsp->buf );
    }

    rsp->buf       = buf;
    rsp->buf_max   = buf_max;
    rsp->buf_len   = buf_len;
    rsp->buf_sent  = sent;
}
コード例 #15
0
ファイル: gr_conn.c プロジェクト: charliexp/grocket
gr_tcp_rsp_t * gr_tcp_rsp_alloc(
    gr_tcp_conn_item_t *    parent,
    int                     buf_max
)
{
    gr_tcp_rsp_t *  rsp;

    if ( NULL == parent || buf_max < 0 ) {
        return NULL;
    }

    rsp = (gr_tcp_rsp_t *)gr_calloc( 1, sizeof( gr_tcp_rsp_t ) );
    if ( NULL == rsp ) {
        gr_fatal( "gr_calloc %d failed: %d", (int)sizeof( gr_tcp_rsp_t ), get_errno() );
        return NULL;
    }

    // 标记字段,必须为1
    rsp->entry.is_tcp   = true;
    // 引用计数为1
    //rsp->entry.refs     = 1;
    // 打个返回标记
    rsp->entry.is_req   = false;

    rsp->parent = parent;
    rsp->buf_max = buf_max;
    if ( rsp->buf_max > 0 ) {
        rsp->buf = (char *)gr_malloc( rsp->buf_max );
        if ( NULL == rsp->buf ) {
            gr_fatal( "gr_malloc %d failed: %d", rsp->buf_max, get_errno() );
            gr_free( rsp );
            return NULL;
        }
    }

    gr_debug( "[fd=%d][cn=%p]alloc rsp %p", parent->fd, parent, rsp );
    return rsp;
}
コード例 #16
0
ファイル: gr_conn.c プロジェクト: charliexp/grocket
void gr_tcp_conn_free(
    gr_tcp_conn_item_t *    conn
)
{
    if ( NULL != conn ) {

        int fd = conn->fd;

#ifdef GR_DEBUG_CONN
        gr_info( "[req.push=%d][req.proc=%d][rsp.send=%llu]free tcp_conn %p",
            conn->req_push_count, conn->req_proc_count, conn->rsp_send_count, conn );
#else
        gr_debug( "[req.push=%d][req.proc=%d]free tcp_conn %p",
            conn->req_push_count, conn->req_proc_count, conn );
#endif
        if ( -1 != conn->fd ) {
            // 关闭连接前回调模块一下
            gr_module_on_tcp_close( conn );
            conn->fd = -1;
        }

        // 删除正在接收的请求
        gr_tcp_conn_del_receiving_req( conn );

        // 删除回复列表
        gr_tcp_conn_clear_rsp_list( conn );

        gr_free( conn );

        gr_debug( "gr_tcp_conn_free leave %p", conn );

        // 关socket
        // we must close the socket at last!!!
        if ( -1 != fd ) {
            gr_socket_close( fd );
        }
    }
}
コード例 #17
0
ファイル: main.c プロジェクト: CharlesGarrocho/MCC
int main(int argc, const char **argv) {

    if (argc < 2) {
        printf("Argumentos Inválidos...\nUtilize: ./a.out <entrada.txt>");
        exit(EXIT_FAILURE);
    }

    const char *endereco = argv[1];
    clock_t start = clock();

    Graph *graph = gr_load(endereco);
    
    iniciar_backtrack(graph);
    iniciar_prim(graph);
    iniciar_branch_bound(graph);

    clock_t end = clock();
    double cpuTime = ((double) (end - start)) / CLOCKS_PER_SEC;
    printf("\nTempo total da execucao: %.2f\n", cpuTime);

    gr_free(graph);

    return EXIT_SUCCESS;
}
コード例 #18
0
ファイル: gr_tcp_in.c プロジェクト: charliexp/grocket
int gr_tcp_in_init()
{
    gr_tcp_in_t *   p;
    int             thread_count;
    int             r;
    int             i;

    thread_count = gr_config_tcp_in_thread_count();
    if ( thread_count < 1 ) {
        gr_fatal( "[init]tcp_in thread_count invalid" );
        return GR_ERR_INVALID_PARAMS;
    }

    if ( NULL != g_ghost_rocket_global.tcp_in ) {
        gr_fatal( "[init]gr_tcp_in_init already called" );
        return GR_ERR_WRONG_CALL_ORDER;
    }

    p = (gr_tcp_in_t *)gr_calloc( 1, sizeof( gr_tcp_in_t ) );
    if ( NULL == p ) {
        gr_fatal( "[init]malloc %d bytes failed, errno=%d,%s",
            (int)sizeof(gr_tcp_in_t), errno, strerror( errno ) );
        return GR_ERR_BAD_ALLOC;
    }

    p->concurrent       = gr_config_tcp_in_concurrent();
    p->is_tcp_in        = true;
    p->worker_disabled  = gr_config_worker_disabled();
    p->tcp_out_disabled = gr_config_tcp_out_disabled();

    r = GR_OK;

    do {

        const char * name = "tcp.input ";

        p->polls = (gr_poll_t**)gr_calloc( 1, sizeof( gr_poll_t * ) * thread_count );
        if ( NULL == p->polls ) {
            gr_fatal( "[init]gr_calloc %d bytes failed",
                (int)sizeof( gr_poll_t * ) * thread_count );
            r = GR_ERR_INIT_POLL_FALED;
            break;
        }

        for ( i = 0; i < thread_count; ++ i ) {
            p->polls[ i ] = gr_poll_create(
                p->concurrent,
                thread_count,
                p->tcp_out_disabled ? (GR_POLLIN | GR_POLLOUT) : GR_POLLIN,
                name );
            if ( NULL == p->polls[ i ] ) {
                gr_fatal( "[init]gr_poll_create return NULL" );
                r = GR_ERR_INIT_POLL_FALED;
                break;
            }
        }
        if ( GR_OK != r ) {
            break;
        }

        r = gr_threads_start(
            & p->threads,
            thread_count,
            NULL,
            tcp_io_worker,
            p,
            gr_poll_raw_buff_for_tcp_in_len(),
            true,
            ENABLE_THREAD,
            name );
        if ( GR_OK != r ) {
            gr_fatal( "[init]gr_threads_start return error %d", r );
            break;
        }

        gr_info( "[init]tcp.in init OK, thread_count=%d, worker.disabled=%d, tcp.out.disabled=%d",
            thread_count, (int)p->worker_disabled, (int)p->tcp_out_disabled );

        r = GR_OK;
    } while ( false );

    if ( GR_OK != r ) {

        gr_threads_close( & p->threads );

        if ( p->polls ) {
            for ( i = 0; i < thread_count; ++ i ) {
                if ( NULL != p->polls[ i ] ) {
                    if ( p->polls[ i ] ) {
                        gr_poll_destroy( p->polls[ i ] );
                        p->polls[ i ] = NULL;
                    }
                }
            }

            gr_free( p->polls );
            p->polls = NULL;
        }

        gr_free( p );
        return r;
    }

    g_ghost_rocket_global.tcp_in = p;
    return GR_OK;
}
コード例 #19
0
ファイル: gr_tcp_out.c プロジェクト: charliexp/grocket
int gr_tcp_out_init()
{
    gr_tcp_out_t *  p;
    bool    tcp_out_disabled= gr_config_tcp_out_disabled();
    int     thread_count    = gr_config_tcp_out_thread_count();
    int     tcp_in_count    = gr_config_tcp_in_thread_count();
    int     udp_in_count    = gr_config_udp_in_thread_count();
    int     r;
    int     i;

    if ( tcp_in_count < 0 || udp_in_count < 0 ) {
        gr_fatal( "[init]tcp_in_count %d or udp_in_count %d invalid",
            tcp_in_count, udp_in_count );
        return GR_ERR_INVALID_PARAMS;
    }

#if ! defined( WIN32 ) && ! defined( WIN64 )
    if ( tcp_out_disabled ) {
        thread_count = tcp_in_count;
    }
#endif
    if ( thread_count < 1 ) {
        gr_fatal( "[init]tcp_out thread_count invalid" );
        return GR_ERR_INVALID_PARAMS;
    }

    if ( NULL != g_ghost_rocket_global.tcp_out ) {
        gr_fatal( "[init]gr_tcp_out_init already called" );
        return GR_ERR_WRONG_CALL_ORDER;
    }

    p = (gr_tcp_out_t *)gr_calloc( 1, sizeof( gr_tcp_out_t ) );
    if ( NULL == p ) {
        gr_fatal( "[init]malloc %d bytes failed, errno=%d,%s",
            (int)sizeof(gr_tcp_out_t), errno, strerror( errno ) );
        return GR_ERR_BAD_ALLOC;
    }

    p->concurrent       = gr_config_tcp_out_concurrent();
    p->is_tcp_in        = false;
    p->worker_disabled  = gr_config_worker_disabled();
    p->tcp_out_disabled = gr_config_tcp_out_disabled();

    r = GR_OK;

    do {

        const char * name   = "tcp.output";

        p->polls = (gr_poll_t**)gr_calloc( 1, sizeof( gr_poll_t * ) * thread_count );
        if ( NULL == p->polls ) {
            gr_fatal( "[init]gr_calloc %d bytes failed",
                (int)sizeof( gr_poll_t * ) * thread_count );
            r = GR_ERR_INIT_POLL_FALED;
            break;
        }

        for ( i = 0; i < thread_count; ++ i ) {
            p->polls[ i ] = gr_poll_create(
                p->concurrent,
                thread_count,
                p->tcp_out_disabled ? (GR_POLLIN | GR_POLLOUT) : GR_POLLOUT,
                name );
            if ( NULL == p->polls[ i ] ) {
                gr_fatal( "[init]gr_poll_create return NULL" );
                r = GR_ERR_INIT_POLL_FALED;
                break;
            }
        }
        if ( GR_OK != r ) {
            break;
        }

        {
            gr_poll_t **    tcp_in_polls;
            int             tcp_in_poll_count;

#if defined( WIN32 ) || defined( WIN64 )
            // windows不允许同一个socket同时加到两个iocp里
            // 这里让tcp_out和tcp_in共用IOCP
            tcp_in_polls = (gr_poll_t **)gr_tcp_in_get_polls( & tcp_in_poll_count );
            for ( i = 0; i < tcp_in_poll_count; ++ i ) {
                r = gr_pool_replace_from(
                    p->polls[ i ],
                    tcp_in_polls[ i ]
                );
                if ( 0 != r ) {
                    gr_fatal( "[init]gr_pool_replace_from return error %d", r );
                    r = GR_ERR_INIT_POLL_FALED;
                    break;
                }
            }
            if ( 0 != r ) {
                break;
            }
            gr_info( "[init]tcp.in and tcp.out use same IOCP" );
#else
            if ( p->tcp_out_disabled ) {
                // 如果要禁用tcp_out,则也要让 tcp_out和tcp_in共用 poll
                tcp_in_polls = (gr_poll_t **)gr_tcp_in_get_polls( & tcp_in_poll_count );
                for ( i = 0; i < tcp_in_poll_count; ++ i ) {
                    r = gr_pool_replace_from(
                        p->polls[ i ],
                        tcp_in_polls[ i ]
                    );
                    if ( 0 != r ) {
                        gr_fatal( "[init]gr_pool_replace_from return error %d", r );
                        r = GR_ERR_INIT_POLL_FALED;
                        break;
                    }
                }
                if ( 0 != r ) {
                    break;
                }
                gr_info( "[init]tcp.in and tcp.out use same gr_poll" );
            }
#endif
        }

        r = gr_threads_start(
            & p->threads,
            thread_count,
            NULL,
            tcp_io_worker,
            p,
            gr_poll_raw_buff_for_tcp_out_len(),
            true,
            p->tcp_out_disabled ? DISABLE_THREAD : ENABLE_THREAD,
            name );
        if ( GR_OK != r ) {
            gr_fatal( "[init]gr_threads_start return error %d", r );
            break;
        }

        if ( p->tcp_out_disabled ) {
            gr_info( "[init]tcp.out.disabled = true" );
        } else {
            gr_info( "[init]tcp.out.disabled = false, tcp.out.thread_count = %d", thread_count );
        }

        gr_debug( "[init]tcp_out_init OK" );

        r = GR_OK;
    } while ( false );

    if ( GR_OK != r ) {

        int thread_count = p->threads.thread_count;
        int i;

        gr_threads_close( & p->threads );

        if ( p->polls ) {
            for ( i = 0; i < thread_count; ++ i ) {
                if ( NULL != p->polls[ i ] ) {
#if ! defined( WIN32 ) && ! defined( WIN64 )
                    if ( ! p->tcp_out_disabled ) {
                        gr_poll_destroy( p->polls[ i ] );
                    }
#endif
                    p->polls[ i ] = NULL;
                }
            }

            gr_free( p->polls );
            p->polls = NULL;
        }

        gr_free( p );
        return r;
    }

    g_ghost_rocket_global.tcp_out = p;
    return GR_OK;
}
コード例 #20
0
ファイル: gr_module.c プロジェクト: xidianwlc/grocket
int gr_module_init(
    gr_version_t    version,
    gr_init_t       init,
    gr_term_t       term,
    gr_tcp_accept_t tcp_accept,
    gr_tcp_close_t  tcp_close,
    gr_check_t      chk_binary,
    gr_proc_t       proc_binary,
    gr_proc_http_t  proc_http)
{
    gr_module_t *   module;
    int             r;

    if ( NULL != g_ghost_rocket_global.module ) {
        gr_fatal( "[init]gr_module_init already called" );
        return GR_ERR_WRONG_CALL_ORDER;
    }

    module = (gr_module_t *)gr_calloc( 1, sizeof( gr_module_t ) );
    if ( NULL == module ) {
        gr_fatal( "[init]malloc %d bytes failed, errno=%d,%s",
                  (int)sizeof(gr_module_t), errno, strerror( errno ) );
        return GR_ERR_BAD_ALLOC;
    }

    module->version     = version;
    module->init        = init;
    module->term        = term;
    module->tcp_accept  = tcp_accept;
    module->tcp_close   = tcp_close;
    module->chk_binary  = chk_binary;
    module->proc_binary = proc_binary;
    module->proc_http   = proc_http;

    r = 0;

    do {

        if (   NULL == module->init
                && NULL == module->term
                && NULL == module->tcp_accept
                && NULL == module->tcp_close
                && NULL == module->chk_binary
                && NULL == module->proc_binary
                && NULL == module->proc_http
           )
        {
            // 没指定用户函数,要装载模块
            char path[ MAX_PATH ] = "";
            bool is_absolute;
            gr_config_get_module_path( path, sizeof( path ), & is_absolute );

            if ( '\0' != path[ 0 ] ) {
                r = module_load( module, path, is_absolute );
                if ( 0 != r ) {
                    gr_fatal( "[init]module_load( %s ) failed, return %d", path, r );
                    break;
                }
            }
        } else {
            if ( NULL == module->version ) {
                gr_fatal( "[init]module->version is NULL" );
                r = GR_ERR_INVALID_PARAMS;
                break;
            }
        }

        if ( ! check_version( module ) ) {
            gr_fatal( "[init]check_version failed" );
            r = GR_ERR_WRONG_VERSION;
            break;
        }

    } while ( false );

    if ( GR_OK != r ) {
        module_unload( module );
        gr_free( module );
        return r;
    }

    g_ghost_rocket_global.module = module;
    return GR_OK;
}
コード例 #21
0
ファイル: gr_conn.c プロジェクト: charliexp/grocket
gr_tcp_req_t * gr_tcp_req_alloc(
    gr_tcp_conn_item_t *    conn,
    int                     buf_max
)
{
    gr_tcp_req_t *  req;
    gr_thread_t *   thread;

    if ( NULL == conn || buf_max < 0 ) {
        gr_fatal( "gr_calloc %d failed: %d", (int)sizeof( gr_tcp_req_t ), get_errno() );
        return NULL;
    }

    // 用worker的线程去分配请求对象
    thread = gr_worker_get_thread_by_tcp_conn( conn );

    if ( thread ) {
        // 从线程 free list 里直接取,不需要分配
        req = thread->free_tcp_req_list;
        if ( req ) {
            thread->free_tcp_req_list = (gr_tcp_req_t *)req->entry.next;

#if defined( WIN32 ) || defined( WIN64 )
            memset( req, 0, sizeof( gr_tcp_req_t ) );
#else
            //gr_queue_item_t             entry;
            //gr_check_base_t                     check_ctxt;
            //gr_tcp_req_t *                      req_list_next;
            //gr_tcp_conn_item_t *                parent;
            //char *                              buf;
            assert( 0 == req->buf_len );
            assert( 0 == req->buf_sent );
#endif
#ifdef GR_DEBUG_CONN
            gr_info( ">>>>>Reborn req %p from thread is %s%d", req, thread->name, thread->id );
#endif
        } else {
            req = (gr_tcp_req_t *)gr_calloc( 1, sizeof( gr_tcp_req_t ) );
            if ( NULL == req ) {
                gr_fatal( "gr_calloc %d failed: %d", (int)sizeof( gr_tcp_req_t ), get_errno() );
                return NULL;
            }
#ifdef GR_DEBUG_CONN
            gr_info( "====Alloc req %p from memory, thread is %s%d", req, thread->name, thread->id );
#endif
        }
    } else {
        req = (gr_tcp_req_t *)gr_calloc( 1, sizeof( gr_tcp_req_t ) );
        if ( NULL == req ) {
            gr_fatal( "gr_calloc %d failed: %d", (int)sizeof( gr_tcp_req_t ), get_errno() );
            return NULL;
        }
#ifdef GR_DEBUG_CONN
        gr_info( "====Alloc req %p from memory, thread invalid", req );
#endif
    }

    // 标记字段,必须为1
    req->entry.is_tcp   = true;
    // 引用计数为1
    //req->entry.refs     = 1;
    // 打个请求标记
    req->entry.is_req   = true;

    req->parent = conn;

    if ( buf_max > req->buf_max ) {
        gr_free( req->buf );

        req->buf_max = buf_max;
        req->buf = (char *)gr_malloc( req->buf_max );
        if ( NULL == req->buf ) {
            gr_fatal( "gr_malloc %d failed: %d", req->buf_max, get_errno() );
            gr_free( req );
            return NULL;
        }
    }

    gr_debug( "[fd=%d][cn=%p]alloc req %p", req->parent->fd, req->parent, req );

    return req;
}