summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/device.c6
-rw-r--r--src/ipconfig.c33
-rw-r--r--src/network.c10
-rw-r--r--src/notifier.c57
-rw-r--r--src/provider.c6
-rw-r--r--src/service.c34
-rw-r--r--src/task.c7
-rw-r--r--src/technology.c21
-rw-r--r--src/tethering.c83
9 files changed, 139 insertions, 118 deletions
diff --git a/src/device.c b/src/device.c
index 9ba7caf7..29da1a13 100644
--- a/src/device.c
+++ b/src/device.c
@@ -39,7 +39,7 @@ enum connman_pending_type {
};
struct connman_device {
- gint refcount;
+ int refcount;
enum connman_device_type type;
enum connman_pending_type powered_pending; /* Indicates a pending
enable/disable request */
@@ -536,7 +536,7 @@ struct connman_device *connman_device_ref(struct connman_device *device)
{
DBG("%p", device);
- g_atomic_int_inc(&device->refcount);
+ __sync_fetch_and_add(&device->refcount, 1);
return device;
}
@@ -549,7 +549,7 @@ struct connman_device *connman_device_ref(struct connman_device *device)
*/
void connman_device_unref(struct connman_device *device)
{
- if (g_atomic_int_dec_and_test(&device->refcount) == FALSE)
+ if (__sync_fetch_and_sub(&device->refcount, 1) != 1)
return;
if (device->driver) {
diff --git a/src/ipconfig.c b/src/ipconfig.c
index da61446e..b4729903 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -40,7 +40,7 @@
#include "connman.h"
struct connman_ipconfig {
- gint refcount;
+ int refcount;
int index;
enum connman_ipconfig_type type;
@@ -1307,10 +1307,9 @@ struct connman_ipconfig *connman_ipconfig_create(int index,
*/
struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig)
{
- DBG("ipconfig %p refcount %d", ipconfig,
- g_atomic_int_get(&ipconfig->refcount) + 1);
+ DBG("ipconfig %p refcount %d", ipconfig, ipconfig->refcount + 1);
- g_atomic_int_inc(&ipconfig->refcount);
+ __sync_fetch_and_add(&ipconfig->refcount, 1);
return ipconfig;
}
@@ -1326,24 +1325,24 @@ void connman_ipconfig_unref(struct connman_ipconfig *ipconfig)
if (ipconfig == NULL)
return;
- DBG("ipconfig %p refcount %d", ipconfig,
- g_atomic_int_get(&ipconfig->refcount) - 1);
+ DBG("ipconfig %p refcount %d", ipconfig, ipconfig->refcount - 1);
- if (g_atomic_int_dec_and_test(&ipconfig->refcount) == TRUE) {
- __connman_ipconfig_disable(ipconfig);
+ if (__sync_fetch_and_sub(&ipconfig->refcount, 1) != 1)
+ return;
- connman_ipconfig_set_ops(ipconfig, NULL);
+ __connman_ipconfig_disable(ipconfig);
- if (ipconfig->origin != NULL) {
- connman_ipconfig_unref(ipconfig->origin);
- ipconfig->origin = NULL;
- }
+ connman_ipconfig_set_ops(ipconfig, NULL);
- connman_ipaddress_free(ipconfig->system);
- connman_ipaddress_free(ipconfig->address);
- g_free(ipconfig->last_dhcp_address);
- g_free(ipconfig);
+ if (ipconfig->origin != NULL) {
+ connman_ipconfig_unref(ipconfig->origin);
+ ipconfig->origin = NULL;
}
+
+ connman_ipaddress_free(ipconfig->system);
+ connman_ipaddress_free(ipconfig->address);
+ g_free(ipconfig->last_dhcp_address);
+ g_free(ipconfig);
}
/**
diff --git a/src/network.c b/src/network.c
index cd0b9c89..090b7e73 100644
--- a/src/network.c
+++ b/src/network.c
@@ -32,7 +32,7 @@ static GSList *network_list = NULL;
static GSList *driver_list = NULL;
struct connman_network {
- gint refcount;
+ int refcount;
enum connman_network_type type;
connman_bool_t available;
connman_bool_t connected;
@@ -389,9 +389,9 @@ struct connman_network *connman_network_create(const char *identifier,
struct connman_network *connman_network_ref(struct connman_network *network)
{
DBG("network %p name %s refcount %d", network, network->name,
- g_atomic_int_get(&network->refcount) + 1);
+ network->refcount + 1);
- g_atomic_int_inc(&network->refcount);
+ __sync_fetch_and_add(&network->refcount, 1);
return network;
}
@@ -405,9 +405,9 @@ struct connman_network *connman_network_ref(struct connman_network *network)
void connman_network_unref(struct connman_network *network)
{
DBG("network %p name %s refcount %d", network, network->name,
- g_atomic_int_get(&network->refcount) - 1);
+ network->refcount - 1);
- if (g_atomic_int_dec_and_test(&network->refcount) == FALSE)
+ if (__sync_fetch_and_sub(&network->refcount, 1) != 1)
return;
network_list = g_slist_remove(network_list, network);
diff --git a/src/notifier.c b/src/notifier.c
index 332bafb1..5ba22649 100644
--- a/src/notifier.c
+++ b/src/notifier.c
@@ -73,21 +73,22 @@ void connman_notifier_unregister(struct connman_notifier *notifier)
#define MAX_TECHNOLOGIES 10
-static volatile gint registered[MAX_TECHNOLOGIES];
-static volatile gint enabled[MAX_TECHNOLOGIES];
-static volatile gint connected[MAX_TECHNOLOGIES];
+static volatile int registered[MAX_TECHNOLOGIES];
+static volatile int enabled[MAX_TECHNOLOGIES];
+static volatile int connected[MAX_TECHNOLOGIES];
void __connman_notifier_list_registered(DBusMessageIter *iter, void *user_data)
{
int i;
+ __sync_synchronize();
for (i = 0; i < MAX_TECHNOLOGIES; i++) {
const char *type = __connman_service_type2string(i);
if (type == NULL)
continue;
- if (g_atomic_int_get(&registered[i]) > 0)
+ if (registered[i] > 0)
dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &type);
}
@@ -97,13 +98,14 @@ void __connman_notifier_list_enabled(DBusMessageIter *iter, void *user_data)
{
int i;
+ __sync_synchronize();
for (i = 0; i < MAX_TECHNOLOGIES; i++) {
const char *type = __connman_service_type2string(i);
if (type == NULL)
continue;
- if (g_atomic_int_get(&enabled[i]) > 0)
+ if (enabled[i] > 0)
dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &type);
}
@@ -113,13 +115,14 @@ void __connman_notifier_list_connected(DBusMessageIter *iter, void *user_data)
{
int i;
+ __sync_synchronize();
for (i = 0; i < MAX_TECHNOLOGIES; i++) {
const char *type = __connman_service_type2string(i);
if (type == NULL)
continue;
- if (g_atomic_int_get(&connected[i]) > 0)
+ if (connected[i] > 0)
dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &type);
}
@@ -158,8 +161,9 @@ unsigned int __connman_notifier_count_connected(void)
{
unsigned int i, count = 0;
+ __sync_synchronize();
for (i = 0; i < MAX_TECHNOLOGIES; i++) {
- if (g_atomic_int_get(&connected[i]) > 0)
+ if (connected[i] > 0)
count++;
}
@@ -238,7 +242,7 @@ void __connman_notifier_register(enum connman_service_type type)
break;
}
- if (g_atomic_int_exchange_and_add(&registered[type], 1) == 0)
+ if (__sync_fetch_and_add(&registered[type], 1) == 0)
technology_registered(type, TRUE);
}
@@ -246,7 +250,8 @@ void __connman_notifier_unregister(enum connman_service_type type)
{
DBG("type %d", type);
- if (g_atomic_int_get(&registered[type]) == 0) {
+ __sync_synchronize();
+ if (registered[type] == 0) {
connman_error("notifier unregister underflow");
return;
}
@@ -266,8 +271,10 @@ void __connman_notifier_unregister(enum connman_service_type type)
break;
}
- if (g_atomic_int_dec_and_test(&registered[type]) == TRUE)
- technology_registered(type, FALSE);
+ if (__sync_fetch_and_sub(&registered[type], 1) != 1)
+ return;
+
+ technology_registered(type, FALSE);
}
void __connman_notifier_enable(enum connman_service_type type)
@@ -289,7 +296,7 @@ void __connman_notifier_enable(enum connman_service_type type)
break;
}
- if (g_atomic_int_exchange_and_add(&enabled[type], 1) == 0)
+ if (__sync_fetch_and_add(&enabled[type], 1) == 0)
technology_enabled(type, TRUE);
}
@@ -297,7 +304,8 @@ void __connman_notifier_disable(enum connman_service_type type)
{
DBG("type %d", type);
- if (g_atomic_int_get(&enabled[type]) == 0) {
+ __sync_synchronize();
+ if (enabled[type] == 0) {
connman_error("notifier disable underflow");
return;
}
@@ -317,8 +325,10 @@ void __connman_notifier_disable(enum connman_service_type type)
break;
}
- if (g_atomic_int_dec_and_test(&enabled[type]) == TRUE)
- technology_enabled(type, FALSE);
+ if (__sync_fetch_and_sub(&enabled[type], 1) != 1)
+ return;
+
+ technology_enabled(type, FALSE);
}
void __connman_notifier_connect(enum connman_service_type type)
@@ -340,7 +350,7 @@ void __connman_notifier_connect(enum connman_service_type type)
break;
}
- if (g_atomic_int_exchange_and_add(&connected[type], 1) == 0)
+ if (__sync_fetch_and_add(&connected[type], 1) == 0)
technology_connected(type, TRUE);
}
@@ -348,7 +358,8 @@ void __connman_notifier_disconnect(enum connman_service_type type)
{
DBG("type %d", type);
- if (g_atomic_int_get(&connected[type]) == 0) {
+ __sync_synchronize();
+ if (connected[type] == 0) {
connman_error("notifier disconnect underflow");
return;
}
@@ -368,8 +379,10 @@ void __connman_notifier_disconnect(enum connman_service_type type)
break;
}
- if (g_atomic_int_dec_and_test(&connected[type]) == TRUE)
- technology_connected(type, FALSE);
+ if (__sync_fetch_and_sub(&connected[type], 1) != 1)
+ return;
+
+ technology_connected(type, FALSE);
}
static void technology_default(enum connman_service_type type)
@@ -577,7 +590,8 @@ connman_bool_t __connman_notifier_is_registered(enum connman_service_type type)
if (technology_supported(type) == FALSE)
return FALSE;
- if (g_atomic_int_get(&registered[type]) > 0)
+ __sync_synchronize();
+ if (registered[type] > 0)
return TRUE;
return FALSE;
@@ -590,7 +604,8 @@ connman_bool_t __connman_notifier_is_enabled(enum connman_service_type type)
if (technology_supported(type) == FALSE)
return FALSE;
- if (g_atomic_int_get(&enabled[type]) > 0)
+ __sync_synchronize();
+ if (enabled[type] > 0)
return TRUE;
return FALSE;
diff --git a/src/provider.c b/src/provider.c
index 7b5edae3..27b09028 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -45,7 +45,7 @@ struct connman_route {
};
struct connman_provider {
- gint refcount;
+ int refcount;
struct connman_service *vpn_service;
int index;
char *identifier;
@@ -213,7 +213,7 @@ struct connman_provider *connman_provider_ref(struct connman_provider *provider)
{
DBG("provider %p refcount %d", provider, provider->refcount + 1);
- g_atomic_int_inc(&provider->refcount);
+ __sync_fetch_and_add(&provider->refcount, 1);
return provider;
}
@@ -235,7 +235,7 @@ void connman_provider_unref(struct connman_provider *provider)
{
DBG("provider %p refcount %d", provider, provider->refcount - 1);
- if (g_atomic_int_dec_and_test(&provider->refcount) == FALSE)
+ if (__sync_fetch_and_sub(&provider->refcount, 1) != 1)
return;
provider_remove(provider);
diff --git a/src/service.c b/src/service.c
index 0026e167..30bf2fb0 100644
--- a/src/service.c
+++ b/src/service.c
@@ -56,8 +56,8 @@ struct connman_stats_counter {
};
struct connman_service {
- gint refcount;
- gint session_usage_count;
+ int refcount;
+ int session_usage_count;
char *identifier;
char *path;
enum connman_service_type type;
@@ -1985,17 +1985,17 @@ GSequence *__connman_service_get_list(struct connman_session *session,
void __connman_service_session_inc(struct connman_service *service)
{
DBG("service %p ref count %d", service,
- g_atomic_int_get(&service->session_usage_count) + 1);
+ service->session_usage_count + 1);
- g_atomic_int_inc(&service->session_usage_count);
+ __sync_fetch_and_add(&service->session_usage_count, 1);
}
connman_bool_t __connman_service_session_dec(struct connman_service *service)
{
DBG("service %p ref count %d", service,
- g_atomic_int_get(&service->session_usage_count) - 1);
+ service->session_usage_count - 1);
- if (g_atomic_int_dec_and_test(&service->session_usage_count) == FALSE)
+ if (__sync_fetch_and_sub(&service->session_usage_count, 1) != 1)
return FALSE;
return TRUE;
@@ -3456,20 +3456,22 @@ static void service_free(gpointer user_data)
*/
void __connman_service_put(struct connman_service *service)
{
+ GSequenceIter *iter;
+
DBG("service %p", service);
- if (g_atomic_int_dec_and_test(&service->refcount) == TRUE) {
- GSequenceIter *iter;
+ if (__sync_fetch_and_sub(&service->refcount, 1) != 1)
+ return;
- iter = g_hash_table_lookup(service_hash, service->identifier);
- if (iter != NULL) {
- reply_pending(service, ECONNABORTED);
+ iter = g_hash_table_lookup(service_hash, service->identifier);
+ if (iter != NULL) {
+ reply_pending(service, ECONNABORTED);
- __connman_service_disconnect(service);
+ __connman_service_disconnect(service);
- g_sequence_remove(iter);
- } else
- service_free(service);
+ g_sequence_remove(iter);
+ } else {
+ service_free(service);
}
}
@@ -3574,7 +3576,7 @@ struct connman_service *connman_service_ref(struct connman_service *service)
{
DBG("%p", service);
- g_atomic_int_inc(&service->refcount);
+ __sync_fetch_and_add(&service->refcount, 1);
return service;
}
diff --git a/src/task.c b/src/task.c
index 2fd2567a..41710cdc 100644
--- a/src/task.c
+++ b/src/task.c
@@ -51,7 +51,7 @@ struct connman_task {
static GHashTable *task_hash = NULL;
-static volatile gint task_counter;
+static volatile int task_counter;
static DBusConnection *connection;
@@ -105,7 +105,7 @@ struct connman_task *connman_task_create(const char *program)
if (task == NULL)
return NULL;
- counter = g_atomic_int_exchange_and_add(&task_counter, 1);
+ counter = __sync_fetch_and_add(&task_counter, 1);
task->path = g_strdup_printf("/task/%d", counter);
task->pid = -1;
@@ -425,7 +425,8 @@ int __connman_task_init(void)
dbus_connection_add_filter(connection, task_filter, NULL, NULL);
- g_atomic_int_set(&task_counter, 0);
+ task_counter = 0;
+ __sync_synchronize();
task_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, free_task);
diff --git a/src/technology.c b/src/technology.c
index c6fd8265..4c816f64 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -51,13 +51,13 @@ enum connman_technology_state {
};
struct connman_technology {
- gint refcount;
+ int refcount;
enum connman_service_type type;
enum connman_technology_state state;
char *path;
GHashTable *rfkill_list;
GSList *device_list;
- gint enabled;
+ int enabled;
char *regdom;
connman_bool_t tethering;
@@ -575,7 +575,7 @@ static struct connman_technology *technology_get(enum connman_service_type type)
technology = technology_find(type);
if (technology != NULL) {
- g_atomic_int_inc(&technology->refcount);
+ __sync_fetch_and_add(&technology->refcount, 1);
goto done;
}
@@ -642,7 +642,7 @@ static void technology_put(struct connman_technology *technology)
{
DBG("technology %p", technology);
- if (g_atomic_int_dec_and_test(&technology->refcount) == FALSE)
+ if (__sync_fetch_and_sub(&technology->refcount, 1) != 1)
return;
if (technology->driver) {
@@ -809,7 +809,7 @@ int __connman_technology_enabled(enum connman_service_type type)
if (technology == NULL)
return -ENXIO;
- if (g_atomic_int_exchange_and_add(&technology->enabled, 1) == 0) {
+ if (__sync_fetch_and_add(&technology->enabled, 1) == 0) {
__connman_notifier_enable(type);
technology->state = CONNMAN_TECHNOLOGY_STATE_ENABLED;
state_changed(technology);
@@ -914,11 +914,12 @@ int __connman_technology_disabled(enum connman_service_type type)
technology->pending_timeout = 0;
}
- if (g_atomic_int_dec_and_test(&technology->enabled) == TRUE) {
- __connman_notifier_disable(type);
- technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
- state_changed(technology);
- }
+ if (__sync_fetch_and_sub(&technology->enabled, 1) != 1)
+ return 0;
+
+ __connman_notifier_disable(type);
+ technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
+ state_changed(technology);
return 0;
}
diff --git a/src/tethering.c b/src/tethering.c
index c362b8d6..b4ab993c 100644
--- a/src/tethering.c
+++ b/src/tethering.c
@@ -65,7 +65,7 @@
#define PRIVATE_NETWORK_SECONDARY_DNS "8.8.4.4"
static char *default_interface = NULL;
-static volatile gint tethering_enabled;
+static volatile int tethering_enabled;
static GDHCPServer *tethering_dhcp_server = NULL;
static DBusConnection *connection;
static GHashTable *pn_hash;
@@ -336,44 +336,44 @@ static void disable_nat(const char *interface)
void __connman_tethering_set_enabled(void)
{
int err;
+ const char *dns;
DBG("enabled %d", tethering_enabled + 1);
- if (g_atomic_int_exchange_and_add(&tethering_enabled, 1) == 0) {
- const char *dns;
+ if (__sync_fetch_and_add(&tethering_enabled, 1) != 0)
+ return;
- err = create_bridge(BRIDGE_NAME);
- if (err < 0)
- return;
+ err = create_bridge(BRIDGE_NAME);
+ if (err < 0)
+ return;
- err = enable_bridge(BRIDGE_NAME);
- if (err < 0) {
- remove_bridge(BRIDGE_NAME);
- return;
- }
+ err = enable_bridge(BRIDGE_NAME);
+ if (err < 0) {
+ remove_bridge(BRIDGE_NAME);
+ return;
+ }
- dns = BRIDGE_IP;
- if (__connman_dnsproxy_add_listener(BRIDGE_NAME) < 0) {
- connman_error("Can't add listener %s to DNS proxy",
+ dns = BRIDGE_IP;
+ if (__connman_dnsproxy_add_listener(BRIDGE_NAME) < 0) {
+ connman_error("Can't add listener %s to DNS proxy",
BRIDGE_NAME);
- dns = BRIDGE_DNS;
- }
-
- tethering_dhcp_server =
- dhcp_server_start(BRIDGE_NAME,
- BRIDGE_IP, BRIDGE_SUBNET,
- BRIDGE_IP_START, BRIDGE_IP_END,
- 24 * 3600, dns);
- if (tethering_dhcp_server == NULL) {
- disable_bridge(BRIDGE_NAME);
- remove_bridge(BRIDGE_NAME);
- return;
- }
-
- enable_nat(default_interface);
-
- DBG("tethering started");
+ dns = BRIDGE_DNS;
+ }
+
+ tethering_dhcp_server =
+ dhcp_server_start(BRIDGE_NAME,
+ BRIDGE_IP, BRIDGE_SUBNET,
+ BRIDGE_IP_START, BRIDGE_IP_END,
+ 24 * 3600, dns);
+ if (tethering_dhcp_server == NULL) {
+ disable_bridge(BRIDGE_NAME);
+ remove_bridge(BRIDGE_NAME);
+ return;
}
+
+ enable_nat(default_interface);
+
+ DBG("tethering started");
}
void __connman_tethering_set_disabled(void)
@@ -382,17 +382,18 @@ void __connman_tethering_set_disabled(void)
__connman_dnsproxy_remove_listener(BRIDGE_NAME);
- if (g_atomic_int_dec_and_test(&tethering_enabled) == TRUE) {
- disable_nat(default_interface);
+ if (__sync_fetch_and_sub(&tethering_enabled, 1) != 1)
+ return;
+
+ disable_nat(default_interface);
- dhcp_server_stop(tethering_dhcp_server);
+ dhcp_server_stop(tethering_dhcp_server);
- disable_bridge(BRIDGE_NAME);
+ disable_bridge(BRIDGE_NAME);
- remove_bridge(BRIDGE_NAME);
+ remove_bridge(BRIDGE_NAME);
- DBG("tethering stopped");
- }
+ DBG("tethering stopped");
}
void __connman_tethering_update_interface(const char *interface)
@@ -410,7 +411,8 @@ void __connman_tethering_update_interface(const char *interface)
default_interface = g_strdup(interface);
- if (!g_atomic_int_get(&tethering_enabled))
+ __sync_synchronize();
+ if (tethering_enabled == 0)
return;
enable_nat(interface);
@@ -613,7 +615,8 @@ void __connman_tethering_cleanup(void)
{
DBG("");
- if (g_atomic_int_get(&tethering_enabled)) {
+ __sync_synchronize();
+ if (tethering_enabled == 0) {
if (tethering_dhcp_server)
dhcp_server_stop(tethering_dhcp_server);
disable_bridge(BRIDGE_NAME);