Skip to content

Commit

Permalink
[worker] Provide thread safe access to current mode data. JB#45312
Browse files Browse the repository at this point in the history
The currently active mode data is owned by the worker thread. Accessing it
from the main thread is not safe.

Add worker_dup_usb_mode_data() function for getting copy of the currently
active mode data in thread safe manner and utilize it from functions that
might get called from the main thread too.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Apr 9, 2019
1 parent 7f42931 commit d3df694
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 35 deletions.
58 changes: 27 additions & 31 deletions src/usb_moded-config.c
Expand Up @@ -623,48 +623,44 @@ char * config_get_network_setting(const char *config)

char *ret = 0;

if(!strcmp(config, NETWORK_IP_KEY))
{
ret = config_get_network_ip();
if(!ret)
ret = strdup("192.168.2.15");
}
else if(!strcmp(config, NETWORK_INTERFACE_KEY))
{
modedata_t *data = 0;

if( !g_strcmp0(config, NETWORK_IP_KEY) ) {
if( !(ret = config_get_network_ip()) )
ret = g_strdup("192.168.2.15");
}
else if( !g_strcmp0(config, NETWORK_INTERFACE_KEY)) {
/* check main configuration before using
* the information from the specific mode */
ret = config_get_network_interface();
if( (ret = config_get_network_interface()) )
goto EXIT;

if(ret)
goto end;
/* no interface override specified, let's use the one
* from the mode config */
const modedata_t *data = worker_get_usb_mode_data();
if(data)
{
if(data->network_interface)
{
ret = strdup(data->network_interface);
goto end;
if( (data = worker_dup_usb_mode_data()) ) {
if( (ret = g_strdup(data->network_interface)) )
goto EXIT;
}

ret = g_strdup("usb0");
}
ret = strdup("usb0");
else if( !g_strcmp0(config, NETWORK_GATEWAY_KEY) ) {
ret = config_get_network_gateway();
}
else if(!strcmp(config, NETWORK_GATEWAY_KEY))
return config_get_network_gateway();
else if(!strcmp(config, NETWORK_NETMASK_KEY))
{
ret = config_get_network_netmask();
if(!ret)
ret = strdup("255.255.255.0");
else if( !g_strcmp0(config, NETWORK_NETMASK_KEY) ) {
if( !(ret = config_get_network_netmask()) )
ret = g_strdup("255.255.255.0");
}
else if(!strcmp(config, NETWORK_NAT_INTERFACE_KEY))
return config_get_network_nat_interface();
else
else if( !g_strcmp0(config, NETWORK_NAT_INTERFACE_KEY) ) {
ret = config_get_network_nat_interface();
}
else {
/* no matching keys, return error */
return NULL;
end:
}

EXIT:
modedata_free(data);

return ret;
}

Expand Down
4 changes: 2 additions & 2 deletions src/usb_moded-network.c
Expand Up @@ -1295,12 +1295,12 @@ 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();
modedata_t *data = worker_dup_usb_mode_data();
if( data && data->network ) {
network_down(data);
network_up(data);
}
modedata_free(data);
}
return 0;
}
33 changes: 31 additions & 2 deletions src/usb_moded-worker.c
Expand Up @@ -61,6 +61,7 @@ const char *worker_get_kernel_module (void);
bool worker_set_kernel_module (const char *module);
void worker_clear_kernel_module (void);
const modedata_t *worker_get_usb_mode_data (void);
modedata_t *worker_dup_usb_mode_data (void);
void worker_set_usb_mode_data (const modedata_t *data);
static const char *worker_get_activated_mode_locked(void);
static bool worker_set_activated_mode_locked(const char *mode);
Expand Down Expand Up @@ -395,8 +396,9 @@ static modedata_t *worker_mode_data = NULL;

/** get the usb mode data
*
* @return a pointer to the usb mode data
* Note: This function should be called only from the worker thread.
*
* @return a pointer to the usb mode data
*/
const modedata_t *worker_get_usb_mode_data(void)
{
Expand All @@ -405,17 +407,41 @@ const modedata_t *worker_get_usb_mode_data(void)
return worker_mode_data;
}

/** get clone of the usb mode data
*
* Caller must release the returned object via #modedata_free().
*
* @return a pointer to the usb mode data
*/
modedata_t *worker_dup_usb_mode_data(void)
{
LOG_REGISTER_CONTEXT;

WORKER_LOCKED_ENTER;

modedata_t *modedata = modedata_copy(worker_mode_data);

WORKER_LOCKED_LEAVE;

return modedata;;
}

/** set the modedata_t data
*
* @param data mode_list_element pointer
* Note: This function should be called only from the worker thread,
*
* @param data mode_list_element pointer
*/
void worker_set_usb_mode_data(const modedata_t *data)
{
LOG_REGISTER_CONTEXT;

WORKER_LOCKED_ENTER;

modedata_free(worker_mode_data),
worker_mode_data = modedata_copy(data);

WORKER_LOCKED_LEAVE;
}

/* ------------------------------------------------------------------------- *
Expand Down Expand Up @@ -962,6 +988,9 @@ worker_quit(void)

worker_stop_thread();
worker_delete_eventfd();

/* Worker thread is stopped and resources can be released. */
worker_set_usb_mode_data(0);
}

void
Expand Down
1 change: 1 addition & 0 deletions src/usb_moded-worker.h
Expand Up @@ -45,6 +45,7 @@ const char *worker_get_kernel_module (void);
bool worker_set_kernel_module (const char *module);
void worker_clear_kernel_module (void);
const modedata_t *worker_get_usb_mode_data (void);
modedata_t *worker_dup_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);
Expand Down

0 comments on commit d3df694

Please sign in to comment.