};
struct connman_device {
- gint refcount;
+ int refcount;
enum connman_device_type type;
enum connman_pending_type powered_pending; /* Indicates a pending
enable/disable request */
{
DBG("%p", device);
- g_atomic_int_inc(&device->refcount);
+ __sync_fetch_and_add(&device->refcount, 1);
return 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) {
#include "connman.h"
struct connman_ipconfig {
- gint refcount;
+ int refcount;
int index;
enum connman_ipconfig_type type;
*/
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;
}
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);
}
/**
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;
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;
}
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);
#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(®istered[i]) > 0)
+ if (registered[i] > 0)
dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &type);
}
{
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);
}
{
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);
}
{
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++;
}
break;
}
- if (g_atomic_int_exchange_and_add(®istered[type], 1) == 0)
+ if (__sync_fetch_and_add(®istered[type], 1) == 0)
technology_registered(type, TRUE);
}
{
DBG("type %d", type);
- if (g_atomic_int_get(®istered[type]) == 0) {
+ __sync_synchronize();
+ if (registered[type] == 0) {
connman_error("notifier unregister underflow");
return;
}
break;
}
- if (g_atomic_int_dec_and_test(®istered[type]) == TRUE)
- technology_registered(type, FALSE);
+ if (__sync_fetch_and_sub(®istered[type], 1) != 1)
+ return;
+
+ technology_registered(type, FALSE);
}
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);
}
{
DBG("type %d", type);
- if (g_atomic_int_get(&enabled[type]) == 0) {
+ __sync_synchronize();
+ if (enabled[type] == 0) {
connman_error("notifier disable underflow");
return;
}
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)
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);
}
{
DBG("type %d", type);
- if (g_atomic_int_get(&connected[type]) == 0) {
+ __sync_synchronize();
+ if (connected[type] == 0) {
connman_error("notifier disconnect underflow");
return;
}
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)
if (technology_supported(type) == FALSE)
return FALSE;
- if (g_atomic_int_get(®istered[type]) > 0)
+ __sync_synchronize();
+ if (registered[type] > 0)
return TRUE;
return FALSE;
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;
};
struct connman_provider {
- gint refcount;
+ int refcount;
struct connman_service *vpn_service;
int index;
char *identifier;
{
DBG("provider %p refcount %d", provider, provider->refcount + 1);
- g_atomic_int_inc(&provider->refcount);
+ __sync_fetch_and_add(&provider->refcount, 1);
return 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);
};
struct connman_service {
- gint refcount;
- gint session_usage_count;
+ int refcount;
+ int session_usage_count;
char *identifier;
char *path;
enum connman_service_type type;
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;
*/
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);
}
}
{
DBG("%p", service);
- g_atomic_int_inc(&service->refcount);
+ __sync_fetch_and_add(&service->refcount, 1);
return service;
}
static GHashTable *task_hash = NULL;
-static volatile gint task_counter;
+static volatile int task_counter;
static DBusConnection *connection;
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;
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);
};
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;
technology = technology_find(type);
if (technology != NULL) {
- g_atomic_int_inc(&technology->refcount);
+ __sync_fetch_and_add(&technology->refcount, 1);
goto done;
}
{
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) {
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);
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;
}
#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;
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)
__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)
default_interface = g_strdup(interface);
- if (!g_atomic_int_get(&tethering_enabled))
+ __sync_synchronize();
+ if (tethering_enabled == 0)
return;
enable_nat(interface);
{
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);