Commit 83df3088 authored by spiiroin's avatar spiiroin

[worker] Use private copy of mode data. JB#45312

When a dynamic mode is activated from the worker thread, a pointer to
shared mode data is cached. If mode data gets invalidated due to the main
thread reloading configuration files, the worker thread will dereference
a stale pointer during mode deactivation.

Cache clone of mode data instead of just holding pointer to shared data.

Note that this only fixes logical error in expected behavior during
config reload, there is still race condition in mode data duplication
stage.
Signed-off-by: spiiroin's avatarSimo Piiroinen <simo.piiroinen@jollamobile.com>
parent 1b916294
......@@ -1295,6 +1295,7 @@ int network_update(void)
LOG_REGISTER_CONTEXT;
if( control_get_cable_state() == CABLE_STATE_PC_CONNECTED ) {
// FIXME: data hazard
const modedata_t *data = worker_get_usb_mode_data();
if( data && data->network ) {
network_down(data);
......
......@@ -69,7 +69,7 @@ static bool worker_set_requested_mode_locked(const char *mode);
void worker_request_hardware_mode (const char *mode);
void worker_clear_hardware_mode (void);
static void worker_execute (void);
void worker_switch_to_mode (const char *mode);
static void worker_switch_to_mode (const char *mode);
static guint worker_add_iowatch (int fd, bool close_on_unref, GIOCondition cnd, GIOFunc io_cb, gpointer aptr);
static void *worker_thread_cb (void *aptr);
static gboolean worker_notify_cb (GIOChannel *chn, GIOCondition cnd, gpointer data);
......@@ -391,7 +391,7 @@ void worker_clear_kernel_module(void)
* ------------------------------------------------------------------------- */
/** Contains the mode data */
static const modedata_t *worker_mode_data = NULL;
static modedata_t *worker_mode_data = NULL;
/** get the usb mode data
*
......@@ -414,7 +414,8 @@ void worker_set_usb_mode_data(const modedata_t *data)
{
LOG_REGISTER_CONTEXT;
worker_mode_data = data;
modedata_free(worker_mode_data),
worker_mode_data = modedata_copy(data);
}
/* ------------------------------------------------------------------------- *
......@@ -546,7 +547,7 @@ worker_execute(void)
* MODE_SWITCH
* ------------------------------------------------------------------------- */
void
static void
worker_switch_to_mode(const char *mode)
{
LOG_REGISTER_CONTEXT;
......
......@@ -48,7 +48,6 @@ const modedata_t *worker_get_usb_mode_data (void);
void worker_set_usb_mode_data (const modedata_t *data);
void worker_request_hardware_mode(const char *mode);
void worker_clear_hardware_mode (void);
void worker_switch_to_mode (const char *mode);
bool worker_init (void);
void worker_quit (void);
void worker_wakeup (void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment