Skip to content
Snippets Groups Projects
Commit 729927d2 authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

Fix a bug with session id in on_disconnect() trigger.

https://bugs.launchpad.net/tarantool/+bug/1160789

When multiple sessions get disconnected at the same
time, the same fiber is running all disconnect triggers.
This fiber's sid was  not changed between trigger invocations,
and on_disconnect() triggrer of the next disconnected
session would see not its own session id in box.session.id(),
but the previous session's session id.

The fix is to correctly set box.session.id() before handling
any iproto request.
In on_connect() request, sid is 0, but soon it is
reset in session_create().

No test case since the bug requires that there is a full
libev queue, so that multiple on_disconnect() triggers
fire in the same loop.
parent 0c9ef5f4
No related branches found
No related tags found
No related merge requests found
......@@ -332,6 +332,9 @@ iproto_queue_init(struct iproto_queue *i_queue,
rlist_init(&i_queue->fiber_cache);
}
static inline uint32_t
iproto_session_id(struct iproto_session *session);
/** A handler to process all queued requests. */
static void
iproto_queue_handler(va_list ap)
......@@ -341,6 +344,7 @@ iproto_queue_handler(va_list ap)
restart:
while (iproto_dequeue_request(i_queue, &request)) {
fiber_set_sid(fiber, iproto_session_id(request.session));
request.process(&request);
}
iproto_cache_fiber(&request_queue);
......@@ -405,6 +409,12 @@ iproto_session_is_idle(struct iproto_session *session)
ibuf_size(&session->iobuf[1]->in) == 0;
}
static inline uint32_t
iproto_session_id(struct iproto_session *session)
{
return session->sid;
}
static void
iproto_session_on_input(struct ev_io *watcher,
int revents __attribute__((unused)));
......@@ -533,7 +543,7 @@ iproto_session_input_iobuf(struct iproto_session *session)
if (ibuf_unused(&old->in) >= to_read)
return old;
/** All requests are procssed, reuse the buffer. */
/** All requests are processed, reuse the buffer. */
if (ibuf_size(&old->in) == session->parse_size) {
ibuf_reserve(&old->in, to_read);
return old;
......@@ -766,7 +776,6 @@ iproto_process_request(struct iproto_request *request)
if (unlikely(! evio_is_connected(&session->output)))
return;
fiber_set_sid(fiber, session->sid);
iproto_reply(&port, *session->handler,
&iobuf->out, header);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment