diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2014-10-23 15:11:43 +0200 |
---|---|---|
committer | David Herrmann <dh.herrmann@gmail.com> | 2014-10-23 15:11:43 +0200 |
commit | dfdedadc2caf0b0098544069f69446f0201da107 (patch) | |
tree | 7978fe70f01780a16c28a57575d79babadead623 /test | |
parent | d343b2e9286800708229ab7e918496a2d48a0a7f (diff) | |
download | kdbus-bus-dfdedadc2caf0b0098544069f69446f0201da107.tar.gz kdbus-bus-dfdedadc2caf0b0098544069f69446f0201da107.tar.bz2 kdbus-bus-dfdedadc2caf0b0098544069f69446f0201da107.zip |
connection: keep SYNC messages alive on EINTR
If a SYNC-SEND is interrupted by a signal, there is no way we can restart
the syscall. If we returned ERESTARTSYS, we'd queue the message again on
restart. This is very irritating, therefore, we never support restarting
syscalls. Instead, we return EINPROGRESS if the message was queued but no
reply was received, yet.
Internally, we turn the 'sync' reply_wait into an 'async' reply. This way,
it will be treated the same way as any other asynchronous reply.
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/test-sync.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/test/test-sync.c b/test/test-sync.c index 9533fd7e1e4..8e69cb356dd 100644 --- a/test/test-sync.c +++ b/test/test-sync.c @@ -71,15 +71,14 @@ static int send_reply(const struct kdbus_conn *conn, } static int interrupt_sync(struct kdbus_conn *conn_src, - struct kdbus_conn *conn_dst, - int sa_flags) + struct kdbus_conn *conn_dst) { pid_t pid; int ret, status; struct kdbus_msg *msg = NULL; struct sigaction sa = { .sa_handler = nop_handler, - .sa_flags = sa_flags, + .sa_flags = SA_NOCLDSTOP|SA_RESTART, }; cookie++; @@ -93,8 +92,20 @@ static int interrupt_sync(struct kdbus_conn *conn_src, ret = kdbus_msg_send(conn_dst, NULL, cookie, KDBUS_MSG_FLAGS_EXPECT_REPLY | KDBUS_MSG_FLAGS_SYNC_REPLY, - 5000000000ULL, 0, conn_src->id); - ASSERT_EXIT(ret == -EINTR); + 100000000ULL, 0, conn_src->id); + ASSERT_EXIT(ret == -EINPROGRESS); + + /* conn_reply is now async, thus we will receive a timeout */ + + ret = kdbus_msg_recv_poll(conn_dst, 100, &msg, NULL); + ASSERT_EXIT(ret >= 0); + + ASSERT_EXIT(msg->size >= sizeof(struct kdbus_msg) + + KDBUS_ITEM_HEADER_SIZE); + ASSERT_EXIT(msg->items[0].size >= KDBUS_ITEM_HEADER_SIZE); + ASSERT_EXIT(msg->items[0].type == KDBUS_ITEM_REPLY_TIMEOUT); + + kdbus_msg_free(msg); _exit(EXIT_SUCCESS); } @@ -113,17 +124,8 @@ static int interrupt_sync(struct kdbus_conn *conn_src, if (WIFSIGNALED(status)) return TEST_ERR; - if (sa_flags & SA_RESTART) { - /* - * Our SYNC logic do not support SA_RESTART flag, so we - * don't receive the same packet again. We fail with - * ETIMEDOUT. - * - * For more information, please check "man 7 signal". - */ - ret = kdbus_msg_recv_poll(conn_src, 100, NULL, NULL); - ASSERT_RETURN(ret == -ETIMEDOUT); - } + ret = kdbus_msg_recv_poll(conn_src, 100, NULL, NULL); + ASSERT_RETURN(ret == -ETIMEDOUT); return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR; } @@ -161,10 +163,7 @@ int kdbus_test_sync_reply(struct kdbus_test_env *env) pthread_join(thread, NULL); ASSERT_RETURN(ret == 0); - ret = interrupt_sync(conn_a, conn_b, SA_NOCLDSTOP); - ASSERT_RETURN(ret == 0); - - ret = interrupt_sync(conn_a, conn_b, SA_NOCLDSTOP|SA_RESTART); + ret = interrupt_sync(conn_a, conn_b); ASSERT_RETURN(ret == 0); kdbus_printf("-- closing bus connections\n"); |