Commit d3df6947 authored by spiiroin's avatar spiiroin

[worker] Provide thread safe access to current mode data. JB#45312

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: spiiroin's avatarSimo Piiroinen <simo.piiroinen@jollamobile.com>
parent 7f42931c
...@@ -617,54 +617,50 @@ set_config_result_t config_set_network_setting(const char *config, const char *s ...@@ -617,54 +617,50 @@ set_config_result_t config_set_network_setting(const char *config, const char *s
return SET_CONFIG_ERROR; return SET_CONFIG_ERROR;
} }
char * config_get_network_setting(const char *config) char *config_get_network_setting(const char *config)
{ {
LOG_REGISTER_CONTEXT; LOG_REGISTER_CONTEXT;
char * ret = 0; char *ret = 0;
if(!strcmp(config, NETWORK_IP_KEY)) modedata_t *data = 0;
{
ret = config_get_network_ip();
if(!ret)
ret = strdup("192.168.2.15");
}
else if(!strcmp(config, NETWORK_INTERFACE_KEY))
{
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 /* check main configuration before using
* the information from the specific mode */ * 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 /* no interface override specified, let's use the one
* from the mode config */ * from the mode config */
const modedata_t *data = worker_get_usb_mode_data(); if( (data = worker_dup_usb_mode_data()) ) {
if(data) if( (ret = g_strdup(data->network_interface)) )
{ goto EXIT;
if(data->network_interface)
{
ret = strdup(data->network_interface);
goto end;
}
} }
ret = strdup("usb0");
ret = g_strdup("usb0");
} }
else if(!strcmp(config, NETWORK_GATEWAY_KEY)) else if( !g_strcmp0(config, NETWORK_GATEWAY_KEY) ) {
return config_get_network_gateway(); ret = config_get_network_gateway();
else if(!strcmp(config, NETWORK_NETMASK_KEY)) }
{ else if( !g_strcmp0(config, NETWORK_NETMASK_KEY) ) {
ret = config_get_network_netmask(); if( !(ret = config_get_network_netmask()) )
if(!ret) ret = g_strdup("255.255.255.0");
ret = strdup("255.255.255.0");
} }
else if(!strcmp(config, NETWORK_NAT_INTERFACE_KEY)) else if( !g_strcmp0(config, NETWORK_NAT_INTERFACE_KEY) ) {
return config_get_network_nat_interface(); ret = config_get_network_nat_interface();
else }
else {
/* no matching keys, return error */ /* no matching keys, return error */
return NULL; }
end:
EXIT:
modedata_free(data);
return ret; return ret;
} }
......
...@@ -1295,12 +1295,12 @@ int network_update(void) ...@@ -1295,12 +1295,12 @@ int network_update(void)
LOG_REGISTER_CONTEXT; LOG_REGISTER_CONTEXT;
if( control_get_cable_state() == CABLE_STATE_PC_CONNECTED ) { if( control_get_cable_state() == CABLE_STATE_PC_CONNECTED ) {
// FIXME: data hazard modedata_t *data = worker_dup_usb_mode_data();
const modedata_t *data = worker_get_usb_mode_data();
if( data && data->network ) { if( data && data->network ) {
network_down(data); network_down(data);
network_up(data); network_up(data);
} }
modedata_free(data);
} }
return 0; return 0;
} }
...@@ -61,6 +61,7 @@ const char *worker_get_kernel_module (void); ...@@ -61,6 +61,7 @@ const char *worker_get_kernel_module (void);
bool worker_set_kernel_module (const char *module); bool worker_set_kernel_module (const char *module);
void worker_clear_kernel_module (void); void worker_clear_kernel_module (void);
const modedata_t *worker_get_usb_mode_data (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_set_usb_mode_data (const modedata_t *data);
static const char *worker_get_activated_mode_locked(void); static const char *worker_get_activated_mode_locked(void);
static bool worker_set_activated_mode_locked(const char *mode); static bool worker_set_activated_mode_locked(const char *mode);
...@@ -395,8 +396,9 @@ static modedata_t *worker_mode_data = NULL; ...@@ -395,8 +396,9 @@ static modedata_t *worker_mode_data = NULL;
/** get the usb mode data /** 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) const modedata_t *worker_get_usb_mode_data(void)
{ {
...@@ -405,17 +407,41 @@ const modedata_t *worker_get_usb_mode_data(void) ...@@ -405,17 +407,41 @@ const modedata_t *worker_get_usb_mode_data(void)
return worker_mode_data; 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 /** 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) void worker_set_usb_mode_data(const modedata_t *data)
{ {
LOG_REGISTER_CONTEXT; LOG_REGISTER_CONTEXT;
WORKER_LOCKED_ENTER;
modedata_free(worker_mode_data), modedata_free(worker_mode_data),
worker_mode_data = modedata_copy(data); worker_mode_data = modedata_copy(data);
WORKER_LOCKED_LEAVE;
} }
/* ------------------------------------------------------------------------- * /* ------------------------------------------------------------------------- *
...@@ -962,6 +988,9 @@ worker_quit(void) ...@@ -962,6 +988,9 @@ worker_quit(void)
worker_stop_thread(); worker_stop_thread();
worker_delete_eventfd(); worker_delete_eventfd();
/* Worker thread is stopped and resources can be released. */
worker_set_usb_mode_data(0);
} }
void void
......
...@@ -45,6 +45,7 @@ const char *worker_get_kernel_module (void); ...@@ -45,6 +45,7 @@ const char *worker_get_kernel_module (void);
bool worker_set_kernel_module (const char *module); bool worker_set_kernel_module (const char *module);
void worker_clear_kernel_module (void); void worker_clear_kernel_module (void);
const modedata_t *worker_get_usb_mode_data (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_set_usb_mode_data (const modedata_t *data);
void worker_request_hardware_mode(const char *mode); void worker_request_hardware_mode(const char *mode);
void worker_clear_hardware_mode (void); void worker_clear_hardware_mode (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