I was thinking about the locking here yesterday and it dawned on me that we
actually don't need this at all:
- possible contention between traversing list to send states to state clients
and adding new state clients to the list:
It is the command handler that adds new state clients to the state client
list. The command handler and the code that actually sends out the container
states run in the same process so there's not contention and thus no locking
needed.
- adding state clients to the list from multiple threads:
The command handler itself is single-threaded so only one thread's request can
be served at the same time so no locking is needed.
- sending out the state to state clients via the command handler itself:
The state client also adds and removes state clients from the state client
list so there's no locking needed.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
return;
}
- process_lock();
lxc_list_for_each_safe(cur, &handler->state_clients, next) {
client = cur->elem;
if (client->clientfd != fd)
*/
break;
}
- process_unlock();
}
static int lxc_cmd_handler(int fd, uint32_t events, void *data,
return -ENOMEM;
}
- process_lock();
state = handler->state;
if (states[state] != 1) {
lxc_list_add_elem(tmplist, newclient);
lxc_list_add_tail(&handler->state_clients, tmplist);
- process_unlock();
} else {
- process_unlock();
free(newclient);
free(tmplist);
return state;
struct state_client *client;
struct lxc_msg msg = {.type = lxc_msg_state, .value = state};
- process_lock();
if (state == THAWED)
handler->state = RUNNING;
else
if (lxc_list_empty(&handler->state_clients)) {
TRACE("No state clients registered");
- process_unlock();
return 0;
}
free(cur->elem);
free(cur);
}
- process_unlock();
return 0;
}