mirror of
https://github.com/schoebel/mars
synced 2025-02-26 17:40:43 +00:00
server: fix wrong sharing of brick lists
This commit is contained in:
parent
8969436177
commit
c0a9790149
@ -317,22 +317,62 @@ int dummy_worker(struct mars_global *global, struct mars_dent *dent, bool prepar
|
||||
static
|
||||
int handler_thread(void *data)
|
||||
{
|
||||
struct mars_global handler_global = {
|
||||
.dent_anchor = LIST_HEAD_INIT(handler_global.dent_anchor),
|
||||
.brick_anchor = LIST_HEAD_INIT(handler_global.brick_anchor),
|
||||
.global_power = {
|
||||
.button = true,
|
||||
},
|
||||
.main_event = __WAIT_QUEUE_HEAD_INITIALIZER(handler_global.main_event),
|
||||
};
|
||||
struct task_struct *thread = NULL;
|
||||
struct server_brick *brick = data;
|
||||
struct mars_socket *sock = &brick->handler_socket;
|
||||
bool ok = mars_get_socket(sock);
|
||||
unsigned long statist_jiffies = jiffies;
|
||||
int debug_nr;
|
||||
int status = -EINVAL;
|
||||
|
||||
init_rwsem(&handler_global.dent_mutex);
|
||||
init_rwsem(&handler_global.brick_mutex);
|
||||
|
||||
MARS_DBG("#%d --------------- handler_thread starting on socket %p\n", sock->s_debug_nr, sock);
|
||||
if (!ok)
|
||||
goto done;
|
||||
|
||||
thread = brick_thread_create(cb_thread, brick, "mars_cb%d", brick->version);
|
||||
if (unlikely(!thread)) {
|
||||
MARS_ERR("cannot create cb thread\n");
|
||||
status = -ENOENT;
|
||||
goto done;
|
||||
}
|
||||
brick->cb_thread = thread;
|
||||
|
||||
brick->handler_running = true;
|
||||
wake_up_interruptible(&brick->startup_event);
|
||||
|
||||
while (!brick_thread_should_stop() && mars_socket_is_alive(sock)) {
|
||||
while (!list_empty(&handler_global.brick_anchor) ||
|
||||
mars_socket_is_alive(sock)) {
|
||||
struct mars_cmd cmd = {};
|
||||
|
||||
handler_global.global_version++;
|
||||
|
||||
if (!list_empty(&handler_global.brick_anchor)) {
|
||||
if (server_show_statist && !time_is_before_jiffies(statist_jiffies + 10 * HZ)) {
|
||||
show_statistics(&handler_global, "handler");
|
||||
statist_jiffies = jiffies;
|
||||
}
|
||||
if (!mars_socket_is_alive(sock) &&
|
||||
atomic_read(&brick->in_flight) <= 0 &&
|
||||
brick->conn_brick) {
|
||||
if (generic_disconnect((void*)brick->inputs[0]) >= 0)
|
||||
brick->conn_brick = NULL;
|
||||
}
|
||||
|
||||
status = mars_kill_brick_when_possible(&handler_global, &handler_global.brick_anchor, false, NULL, true);
|
||||
MARS_DBG("kill handler bricks (when possible) = %d\n", status);
|
||||
}
|
||||
|
||||
status = -EINTR;
|
||||
if (unlikely(!mars_global || !mars_global->global_power.button)) {
|
||||
MARS_DBG("system is not alive\n");
|
||||
@ -390,33 +430,21 @@ int handler_thread(void *data)
|
||||
}
|
||||
case CMD_GETENTS:
|
||||
{
|
||||
struct mars_global local = {
|
||||
.dent_anchor = LIST_HEAD_INIT(local.dent_anchor),
|
||||
.brick_anchor = LIST_HEAD_INIT(local.brick_anchor),
|
||||
.global_power = {
|
||||
.button = true,
|
||||
},
|
||||
.main_event = __WAIT_QUEUE_HEAD_INITIALIZER(local.main_event),
|
||||
};
|
||||
|
||||
status = -EINVAL;
|
||||
if (unlikely(!cmd.cmd_str1))
|
||||
break;
|
||||
|
||||
init_rwsem(&local.dent_mutex);
|
||||
init_rwsem(&local.brick_mutex);
|
||||
|
||||
status = mars_dent_work(&local, "/mars", sizeof(struct mars_dent), light_checker, dummy_worker, &local, 3);
|
||||
status = mars_dent_work(&handler_global, "/mars", sizeof(struct mars_dent), light_checker, dummy_worker, &handler_global, 3);
|
||||
|
||||
down(&brick->socket_sem);
|
||||
status = mars_send_dent_list(sock, &local.dent_anchor);
|
||||
status = mars_send_dent_list(sock, &handler_global.dent_anchor);
|
||||
up(&brick->socket_sem);
|
||||
|
||||
if (status < 0) {
|
||||
MARS_WRN("#%d could not send dentry information, status = %d\n", sock->s_debug_nr, status);
|
||||
}
|
||||
|
||||
mars_free_dent_all(&local, &local.dent_anchor);
|
||||
mars_free_dent_all(&handler_global, &handler_global.dent_anchor);
|
||||
break;
|
||||
}
|
||||
case CMD_CONNECT:
|
||||
@ -429,7 +457,7 @@ int handler_thread(void *data)
|
||||
CHECK_PTR_NULL(_bio_brick_type, err);
|
||||
|
||||
prev = make_brick_all(
|
||||
brick->global,
|
||||
&handler_global,
|
||||
NULL,
|
||||
_set_server_bio_params,
|
||||
NULL,
|
||||
@ -446,6 +474,7 @@ int handler_thread(void *data)
|
||||
MARS_ERR("#%d cannot connect to '%s'\n", sock->s_debug_nr, path);
|
||||
}
|
||||
prev->killme = true;
|
||||
brick->conn_brick = prev;
|
||||
} else {
|
||||
MARS_ERR("#%d cannot find brick '%s'\n", sock->s_debug_nr, path);
|
||||
}
|
||||
@ -490,6 +519,15 @@ int handler_thread(void *data)
|
||||
done:
|
||||
MARS_DBG("#%d handler_thread terminating, status = %d\n", sock->s_debug_nr, status);
|
||||
|
||||
mars_kill_brick_all(&handler_global, &handler_global.brick_anchor, false);
|
||||
|
||||
if (thread) {
|
||||
brick->cb_thread = NULL;
|
||||
brick->cb_running = false;
|
||||
MARS_DBG("#%d stopping callback thread....\n", sock->s_debug_nr);
|
||||
brick_thread_stop(thread);
|
||||
}
|
||||
|
||||
debug_nr = sock->s_debug_nr;
|
||||
|
||||
MARS_DBG("#%d done.\n", debug_nr);
|
||||
@ -544,18 +582,10 @@ static int server_switch(struct server_brick *brick)
|
||||
|
||||
mars_power_led_off((void*)brick, false);
|
||||
|
||||
brick->cb_thread = brick_thread_create(cb_thread, brick, "mars_cb%d", version);
|
||||
if (unlikely(!brick->cb_thread)) {
|
||||
MARS_ERR("cannot create cb thread\n");
|
||||
status = -ENOENT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
brick->handler_thread = brick_thread_create(handler_thread, brick, "mars_handler%d", version++);
|
||||
brick->version = version++;
|
||||
brick->handler_thread = brick_thread_create(handler_thread, brick, "mars_handler%d", brick->version);
|
||||
if (unlikely(!brick->handler_thread)) {
|
||||
MARS_ERR("cannot create handler thread\n");
|
||||
brick_thread_stop(brick->cb_thread);
|
||||
brick->cb_thread = NULL;
|
||||
status = -ENOENT;
|
||||
goto err;
|
||||
}
|
||||
@ -574,13 +604,6 @@ static int server_switch(struct server_brick *brick)
|
||||
MARS_DBG("#%d stopping handler thread....\n", sock->s_debug_nr);
|
||||
brick_thread_stop(thread);
|
||||
}
|
||||
thread = brick->cb_thread;
|
||||
if (thread) {
|
||||
brick->cb_thread = NULL;
|
||||
brick->cb_running = false;
|
||||
MARS_DBG("#%d stopping callback thread....\n", sock->s_debug_nr);
|
||||
brick_thread_stop(thread);
|
||||
}
|
||||
|
||||
mars_put_socket(sock);
|
||||
MARS_DBG("#%d socket s_count = %d\n", sock->s_debug_nr, atomic_read(&sock->s_count));
|
||||
|
@ -48,9 +48,9 @@ struct server_output {
|
||||
|
||||
struct server_brick {
|
||||
MARS_BRICK(server);
|
||||
atomic_t in_flight;
|
||||
struct semaphore socket_sem;
|
||||
struct mars_socket handler_socket;
|
||||
struct mars_brick *conn_brick;
|
||||
struct task_struct *handler_thread;
|
||||
struct task_struct *cb_thread;
|
||||
wait_queue_head_t startup_event;
|
||||
@ -58,6 +58,8 @@ struct server_brick {
|
||||
spinlock_t cb_lock;
|
||||
struct list_head cb_read_list;
|
||||
struct list_head cb_write_list;
|
||||
atomic_t in_flight;
|
||||
int version;
|
||||
bool cb_running;
|
||||
bool handler_running;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user