re-wrote iterate over linked list and delete element code

This commit is contained in:
matthias.ringwald 2010-08-23 21:03:40 +00:00
parent 3a35442530
commit 15ec09bb89
2 changed files with 25 additions and 20 deletions

View File

@ -276,17 +276,19 @@ void l2cap_disconnect_internal(uint16_t local_cid, uint8_t reason){
}
static void l2cap_handle_connection_failed_for_addr(bd_addr_t address, uint8_t status){
linked_item_t *it;
for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){
l2cap_channel_t * channel = (l2cap_channel_t *) it;
linked_item_t *it = (linked_item_t *) &l2cap_channels;
while (it->next){
l2cap_channel_t * channel = (l2cap_channel_t *) it->next;
if ( ! BD_ADDR_CMP( channel->address, address) ){
if (channel->state == L2CAP_STATE_CLOSED) {
// failure, forward error code
l2cap_emit_channel_opened(channel, status);
// discard channel
linked_list_remove(&l2cap_channels, (linked_item_t *) channel);
it->next = it->next->next;
free (channel);
}
} else {
it = it->next;
}
}
}
@ -343,13 +345,16 @@ void l2cap_event_handler( uint8_t *packet, uint16_t size ){
case HCI_EVENT_DISCONNECTION_COMPLETE:
// send l2cap disconnect events for all channels on this handle
handle = READ_BT_16(packet, 3);
// only access next element to allows for removal
for (it = (linked_item_t *) &l2cap_channels; it->next ; it = it->next){
it = (linked_item_t *) &l2cap_channels;
while (it->next){
l2cap_channel_t * channel = (l2cap_channel_t *) it->next;
if ( channel->handle == handle ){
// update prev item before free'ing next element
it->next = it->next->next;
l2cap_finialize_channel_close(channel);
// update prev item before free'ing next element - don't call l2cap_finalize_channel_close
it->next->next = it->next;
l2cap_emit_channel_closed(channel);
free (channel);
} else {
it = it->next;
}
}
break;
@ -764,11 +769,10 @@ static void l2cap_packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t
}
}
// finalize closed channel
// finalize closed channel - l2cap_handle_disconnect_request & DISCONNECTION_RESPONSE
void l2cap_finialize_channel_close(l2cap_channel_t *channel){
channel->state = L2CAP_STATE_CLOSED;
l2cap_emit_channel_closed(channel);
// discard channel
linked_list_remove(&l2cap_channels, (linked_item_t *) channel);
free (channel);
@ -830,7 +834,7 @@ void l2cap_close_connection(void *connection){
// unregister services
it = (linked_item_t *) &l2cap_services;
while (it->next){
while (it->next) {
l2cap_service_t * service = (l2cap_service_t *) it->next;
if (service->connection == connection){
it->next = it->next->next;

View File

@ -172,6 +172,8 @@ int socket_connection_hci_process(struct data_source *ds) {
int bytes_read = read(ds->fd, &conn->buffer[conn->bytes_read], conn->bytes_to_read);
if (bytes_read <= 0){
fprintf(stderr, "socket_connection_hci_process read bytes %d\n", bytes_read);
// connection broken (no particular channel, no date yet)
uint8_t event[1];
event[0] = DAEMON_EVENT_CONNECTION_CLOSED;
@ -185,7 +187,7 @@ int socket_connection_hci_process(struct data_source *ds) {
}
conn->bytes_read += bytes_read;
conn->bytes_to_read -= bytes_read;
// hexdump( conn->buffer, conn->bytes_read);
if (conn->bytes_to_read > 0) {
return 0;
}
@ -222,11 +224,9 @@ int socket_connection_hci_process(struct data_source *ds) {
*/
void socket_connection_retry_parked(){
// log_dbg("socket_connection_hci_process retry parked\n");
linked_item_t *next;
linked_item_t *it;
for (it = (linked_item_t *) parked; it ; it = next){
next = it->next; // cache pointer to next connection_t to allow for removal
connection_t * conn = (connection_t *) it;
linked_item_t *it = (linked_item_t *) &parked;
wile (it->next) {
connection_t * conn = (connection_t *) it->next;
// dispatch packet !!! connection, type, channel, data, size
log_dbg("socket_connection_hci_process retry parked #0\n");
@ -235,8 +235,10 @@ void socket_connection_retry_parked(){
// "un-park" if successful
if (!dispatch_err) {
log_dbg("socket_connection_hci_process dispatch succeeded -> un-park connection\n");
linked_list_remove(&parked, it);
it->next = it->next->next;
run_loop_add_data_source( (data_source_t *) conn);
} else {
it = it->next;
}
}
}
@ -464,7 +466,6 @@ void socket_connection_register_packet_callback( int (*packet_callback)(connecti
* send HCI packet to single connection
*/
void socket_connection_send_packet(connection_t *conn, uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){
uint8_t header[sizeof(packet_header_t)];
bt_store_16(header, 0, type);
bt_store_16(header, 2, channel);