1

Here I am try to get xpc reply within a second. I don't want to block the whole application so I am try to check the result after 1 second. but it always crash in sleep(1). Does anyone know what is the best way to do like this?

I tried sleep(1), std::this_thread::sleep_for(2s); and dispatch_group_wait but no luck. Every time when the thread wake up it crash, following is the code I call xpc and retrive the value after 1 second.

// send message
static int result = ETIME;
xpc_connection_send_message_with_reply(mConn, msg, NULL, ^(xpc_object_t reply){
    if (reply == XPC_ERROR_CONNECTION_INVALID || reply == XPC_ERROR_CONNECTION_INTERRUPTED) {
        result = ENOTCONN;
    }
    if (xpc_get_type(reply) != XPC_TYPE_DICTIONARY) {
        result = EINVAL;
    }
    result = (int)xpc_dictionary_get_int64(reply, sResult);
    xpc_release(reply);
    printf("leave\n");
});
// wait 1 second for result
//dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC);
std::this_thread::sleep_for(2s); // crash happened
TQ.Liu
  • 81
  • 6

1 Answers1

1

after a lot of research finally fix it. to achieve this the best way is to let GCD do the job as follow and the crash is not caused by sleep actually it is caused by xpc_release(reply); this should call in server side. More detail you need check http://www.manpagez.com/man/3/xpc_connection_send_message_with_reply_sync/ at REPLY MESSAGES section. all in all check the fix:

static int result = ETIME;
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
xpc_connection_send_message_with_reply(mConn, msg, NULL, ^(xpc_object_t reply){
    // reply will be release in server sige
    // so never call xpc_release(reply) here
    // or it will crash when it finish
    if (reply == XPC_ERROR_CONNECTION_INVALID || reply == XPC_ERROR_CONNECTION_INTERRUPTED) {
        result = ENOTCONN;
    }
    if (xpc_get_type(reply) != XPC_TYPE_DICTIONARY) {
        result = EINVAL;
    }
    result = (int)xpc_dictionary_get_int64(reply, sResult);
    // xpc_release(reply); !!! call this in server side or will crash here !!!
    dispatch_group_leave(group);
    printf("leave\n");
});
// wait 1 second for result
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC);
dispatch_group_wait(group, timeout);
printf("end\n");
TQ.Liu
  • 81
  • 6