AT: Fixed mistake that caused SIGSEGV on unqueue code
authorPaul Kocialkowski <contact@paulk.fr>
Fri, 27 Jul 2012 17:08:07 +0000 (19:08 +0200)
committerPaul Kocialkowski <contact@paulk.fr>
Fri, 27 Jul 2012 17:08:07 +0000 (19:08 +0200)
Device: Unlock responses queue after handling all the read requests

Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
at.c
device.c

diff --git a/at.c b/at.c
index 2356730..6b55f8e 100644 (file)
--- a/at.c
+++ b/at.c
@@ -490,6 +490,14 @@ void at_responses_handling_sync_clean(void)
  * Responses queue
  */
 
+void at_responses_queue_unlock(void)
+{
+       // Only unlock if there are responses available
+       if(at_responses_handling.responses_queue.responses_count > 0 && at_responses_handling.responses_queue.responses != NULL) {
+               AT_RESPONSES_QUEUE_UNLOCK();
+       }
+}
+
 int at_response_queue(struct at_response *response)
 {
        struct at_response **responses = NULL;
@@ -528,8 +536,6 @@ int at_response_queue(struct at_response *response)
 
        AT_RESPONSES_UNLOCK();
 
-       AT_RESPONSES_QUEUE_UNLOCK();
-
        return 0;
 }
 
@@ -547,7 +553,7 @@ struct at_response *at_response_dequeue(void)
        responses = at_responses_handling.responses_queue.responses;
        responses_count = at_responses_handling.responses_queue.responses_count;
 
-       if(responses_count <= 0 || responses == NULL) {
+       while(responses_count <= 0 || responses == NULL) {
                LOGE("No response queued, blocking!");
 
                AT_RESPONSES_UNLOCK();
@@ -556,6 +562,8 @@ struct at_response *at_response_dequeue(void)
 
                responses = at_responses_handling.responses_queue.responses;
                responses_count = at_responses_handling.responses_queue.responses_count;
+
+               LOGE("Unblocking: %d new responses queued!", responses_count);
        }
 
        for(i=0 ; i < responses_count ; i++) {
@@ -575,7 +583,7 @@ struct at_response *at_response_dequeue(void)
        responses[pos] = NULL;
 
        // Move the elements back
-       for(i=pos ; i < responses_count-1 ; i--) {
+       for(i=pos ; i < responses_count-1 ; i++) {
                responses[i] = responses[i+1];
        }
 
@@ -666,7 +674,7 @@ void at_request_expect_to_func_dequeue(struct at_async_request *request)
        requests[pos] = NULL;
 
        // Move the elements back
-       for(i=pos ; i < requests_count-1 ; i--) {
+       for(i=pos ; i < requests_count-1 ; i++) {
                requests[i] = requests[i+1];
        }
 
index 0723e87..f9a55d7 100644 (file)
--- a/device.c
+++ b/device.c
@@ -367,6 +367,7 @@ int ril_device_recv_loop(struct ril_device *ril_device_p)
 {
        struct at_response **responses = NULL;
        int responses_count = 0;
+       int responses_queued = 0;
 
        char *data = NULL;
        int length = 0;
@@ -397,6 +398,7 @@ int ril_device_recv_loop(struct ril_device *ril_device_p)
                                 i = 5;
 
                        responses_count = at_responses_process(&responses, data, length);
+                       responses_queued = 0;
 
                        // Log response
                        RIL_LOG_LOCK();
@@ -416,10 +418,16 @@ int ril_device_recv_loop(struct ril_device *ril_device_p)
                                        if(rc < 0) {
                                                LOGE("Failed to queue response, clearing!");
                                                at_response_free(responses[j]);
+                                       } else {
+                                               responses_queued = 1;
                                        }
                                }
                        }
 
+                       // Unlock the queue after adding all the requests to the queue (if any)
+                       if(responses_queued)
+                               at_responses_queue_unlock();
+
                        free(data);
                }