Linux: LAD_client: Avoid hang in fopen during connect
authorAngela Stegmaier <angelabaker@ti.com>
Wed, 26 Jul 2017 14:57:00 +0000 (09:57 -0500)
committerAngela Stegmaier <angelabaker@ti.com>
Thu, 3 Aug 2017 16:44:01 +0000 (11:44 -0500)
If the application is started and calls Ipc_start before
the LAD is started and created/opened the fifo, then
the application can block in the fopen trying to connect
to the command FIFO.

This patch makes the sequence more robust by first checking
if the fifo exists, then trying to open it as non-blocking,
thereby getting an immediate success or error instead of
blocking until it has been opened for reading by LAD. Once
the non-blocking open returns successfully, the regular
connect sequence can continue. If it returns with a failure,
it will sleep and then try again for a period of time,
eventually returning a timeout failure if it is unable
to connect. This should prevent the application from hanging
if LAD is not started before it calls Ipc_start.

Signed-off-by: Angela Stegmaier <angelabaker@ti.com>
linux/src/utils/LAD_client.c

index 3aafb67eb870b6925e60688ae4f0b968fd58f686..390e9c5b0c94c4aef05bea8165e2af870a1b79fd 100644 (file)
@@ -388,8 +388,36 @@ static LAD_Status initWrappers(Void)
  */
 static Bool openCommandFIFO(Void)
 {
  */
 static Bool openCommandFIFO(Void)
 {
+    time_t currentTime;
+    time_t startTime;
+    struct stat statBuf;
+    double delta = 0;
+    int commandFIFOFd = 0;
     int flags;
 
     int flags;
 
+    startTime = time ((time_t *) 0);
+    while (delta <= LAD_CONNECTTIMEOUT) {
+        /* check if FIFO exists. LAD daemon will be creating it,
+         * we don't want the client to create it */
+        if (stat(commandFIFOFileName, &statBuf) == 0) {
+            /* open a file for writing to FIFO, non-blocking */
+            commandFIFOFd = open(commandFIFOFileName, O_WRONLY | O_TRUNC | O_NONBLOCK);
+            if (commandFIFOFd != -1) {
+                close(commandFIFOFd);
+                break;
+            }
+        }
+        PRINTVERBOSE0("\nLAD_connect: LAD is not yet running, will retry\n")
+        usleep(100);
+        currentTime = time ((time_t *) 0);
+        delta = difftime(currentTime, startTime);
+    }
+
+    if (delta > LAD_CONNECTTIMEOUT) {
+        PRINTVERBOSE0("\nERROR: timed out waiting for LAD to be started\n");
+        return(FALSE);
+    }
+
     /* open a file for writing to FIFO */
     commandFIFOFilePtr = fopen(commandFIFOFileName, "w");
 
     /* open a file for writing to FIFO */
     commandFIFOFilePtr = fopen(commandFIFOFileName, "w");