gattlib_disconnect: Add mutex to avoid double free

pull/266/head
Olivier Martin 2024-02-15 19:24:33 +01:00 committed by Olivier Martin
parent 7f6979c82b
commit f894c8e23a
3 changed files with 26 additions and 10 deletions

View File

@ -42,6 +42,8 @@ struct gattlib_handler {
struct _gatt_connection_t {
void* context;
GMutex connection_mutex;
struct gattlib_handler on_connection;
struct gattlib_handler on_connection_error;
struct gattlib_handler notification;

View File

@ -281,6 +281,7 @@ gatt_connection_t *gattlib_connect_async(void *adapter, const char *dst,
int gattlib_disconnect(gatt_connection_t* connection) {
gattlib_context_t* conn_context;
int ret = GATTLIB_SUCCESS;
GError *error = NULL;
if (connection == NULL) {
@ -288,16 +289,15 @@ int gattlib_disconnect(gatt_connection_t* connection) {
return GATTLIB_INVALID_PARAMETER;
}
g_mutex_lock(&connection->connection_mutex);
conn_context = connection->context;
if (conn_context == NULL) {
GATTLIB_LOG(GATTLIB_ERROR, "Cannot disconnect - connection context is not valid.");
return GATTLIB_NOT_SUPPORTED;
ret = GATTLIB_NOT_SUPPORTED;
goto EXIT;
}
// Remove signal
g_signal_handler_disconnect(conn_context->device, conn_context->on_handle_device_property_change_id);
org_bluez_device1_call_disconnect_sync(conn_context->device, NULL, &error);
if (error) {
GATTLIB_LOG(GATTLIB_ERROR, "Failed to disconnect DBus Bluez Device: %s", error->message);
@ -308,7 +308,10 @@ int gattlib_disconnect(gatt_connection_t* connection) {
gattlib_on_disconnected_device(connection);
free(conn_context->device_object_path);
g_object_unref(conn_context->device);
if (conn_context->device != NULL) {
g_object_unref(conn_context->device);
conn_context->device = NULL;
}
g_list_free_full(conn_context->dbus_objects, g_object_unref);
g_main_loop_quit(conn_context->connection_loop);
pthread_join(conn_context->event_thread, NULL);
@ -318,8 +321,12 @@ int gattlib_disconnect(gatt_connection_t* connection) {
// Note: We do not free adapter as it might still be used by other devices
free(connection->context);
connection->context = NULL;
free(connection);
return GATTLIB_SUCCESS;
EXIT:
g_mutex_unlock(&connection->connection_mutex);
return ret;
}
// Bluez was using org.bluez.Device1.GattServices until 5.37 to expose the list of available GATT Services

View File

@ -7,6 +7,7 @@
from __future__ import annotations
import logging
import uuid
import threading
from typing import TYPE_CHECKING
from gattlib import *
@ -39,6 +40,8 @@ class Device:
self._addr = addr
self._name = name
self._connection = None
self._connection_lock = threading.Lock()
self.on_connection_callback = None
self.on_connection_error_callback = None
@ -114,10 +117,14 @@ class Device:
gattlib_python_callback_args(on_disconnection, user_data))
def disconnect(self):
if self._connection:
ret = gattlib_disconnect(self.connection)
handle_return(ret)
self._connection = None
self._connection_lock.acquire()
try:
if self._connection:
ret = gattlib_disconnect(self.connection)
handle_return(ret)
self._connection = None
finally:
self._connection_lock.release()
def discover(self):
#