2012-04-11 1 views
0

내 GMainContext에 대해 ref_count가 올바르게 감소하지 않습니다. 예제 프로그램은 큰 프로그램의 작은 버전입니다 (스레드를 사용하므로 컨텍스트를 만들어 스레드에 밀어 넣어야합니다). 내가 예상대로 다른 g_main_context_unref(ctx); 모든 것이 종료 할 경우GMainContext가 unref 다음에 ref_count> 0을 가짐

(gdb) p ctx->ref_count 
$2 = 1 

: 그 CTX을 볼 수 있습니다 단지 반환하기 전에 중단 점을 삽입, GDB를 사용

GMainLoop *loop; 
GMainContext *ctx; 

struct conn 
{ 
    GSocketClient *client; 

    GSocketConnection *conn; 
    GInputStream *in; 
    GOutputStream *out; 

    gchar data[8192]; 
    unsigned int count; 
}; 

static void 
read_done_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) 
{ 
    struct conn *c = (struct conn *)user_data; 
    gssize len = g_input_stream_read_finish(c->in, res, NULL); 

    g_input_stream_read_async(c->in, c->data, sizeof c->data/sizeof *c->data, G_PRIORITY_DEFAULT, NULL, read_done_cb, c); 
    if (c->count++ == 1) { 
     printf("End of life as I know it...\n"); 
     g_main_loop_quit(loop); 
    } 
} 

static void 
write_done_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) 
{ 
} 

static void 
connect_done_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) 
{ 
    printf("## %s\n", __FUNCTION__); 

    struct conn *c = (struct conn *)user_data; 
    c->conn = g_socket_client_connect_to_host_finish(c->client, res, NULL); 

    c->in = g_io_stream_get_input_stream(G_IO_STREAM(c->conn)); 
    c->out = g_io_stream_get_output_stream(G_IO_STREAM(c->conn)); 

    char *data = "GET /axis-cgi/mjpg/video.cgi HTTP/1.0\r\n\r\n"; 

    g_output_stream_write_async(c->out, data, strlen(data), G_PRIORITY_DEFAULT, NULL, write_done_cb, c); 
    g_input_stream_read_async(c->in, c->data, sizeof c->data/sizeof *c->data, G_PRIORITY_DEFAULT, NULL, read_done_cb, c); 
} 

int 
main(int argc, char **argv) 
{ 
    g_type_init(); 

    struct conn *c = g_malloc0(sizeof *c); 
    ctx = g_main_context_new(); 
    loop = g_main_loop_new(ctx, FALSE); 
    g_main_context_push_thread_default(ctx); 

    c->client = g_socket_client_new(); 
    g_socket_client_connect_to_host_async(c->client, "10.85.25.20", 80, NULL, connect_done_cb, c); 

    g_main_loop_run(loop); 

    g_io_stream_close(G_IO_STREAM(c->conn), NULL, NULL); 
    g_object_unref(c->client); 
    g_object_unref(c->conn); 
    g_main_context_pop_thread_default(ctx); 
    g_main_loop_unref(loop); 
    g_main_context_unref(ctx); 

    return 0; 
} 

는 여전히 하나의 심판이 카운트를 가지고있다. 나는이 소유권을 어디서 얻을 수 있는지 이해하지 못한다. 당신의 도움에 미리

덕분에

답변

1

오류를 발견했습니다. I read_done_cb 메인 루프를 종료 한 직후에 g_input_stream_read_async을 발행했습니다. g_input_stream_read_async이 ref_count를 올렸지 만 GMainLoop은 내 콜백으로 돌아갈 기회를 얻지 못했습니다. 내 GMainContext의 ref_count가 감소했습니다.

static void 
read_done_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) 
{ 
    struct conn *c = (struct conn *)user_data; 
    gssize len = g_input_stream_read_finish(c->in, res, NULL); 

    if (c->count++ == 1) { 
     printf("End of life as I know it...\n"); 
     g_main_loop_quit(loop); 
    } 

    g_input_stream_read_async(c->in, c->data, sizeof c->data/sizeof *c->data, G_PRIORITY_DEFAULT, NULL, read_done_cb, c); 

} 

경우 아래로 내 콜백 g_input_stream_read_async에 대한 호출을 이동 제대로 내 주요 상황에 심판이 카운트의 수를 해결.

어리석은 실수. 잘만되면 누군가 적어도 내 게시물의 일부 사용을 찾을 수 있습니다.

0

g_main_context_new(), g_main_loop_new()g_main_context_push_thread_default() 모든 상황을 심판. g_main_context_pop_thread_default(), g_main_loop_unref()g_main_context_unref() 모두 참조하십시오. 그래서 당신의 직감은 건전합니다.

gdb : watch ctx->ref_count에서 감시 점을 사용하여 추가 참조가 추가되는 위치를 확인합니다.

관련 문제