VFS: Allocate socket select semaphore outside ISR
authorRoland Dobai <dobai.roland@gmail.com>
Mon, 1 Apr 2019 10:50:54 +0000 (12:50 +0200)
committerRoland Dobai <dobai.roland@gmail.com>
Mon, 13 May 2019 09:20:15 +0000 (11:20 +0200)
components/lwip/port/vfs_lwip.c
components/vfs/include/esp_vfs.h
components/vfs/vfs.c

index 54d71912bb85230a9975ef04f41e6e1cc3580503..c795fbe8004fc75bb5f2ff0cf59cffd950bbfd85 100644 (file)
@@ -40,6 +40,14 @@ static void lwip_stop_socket_select_isr(BaseType_t *woken)
     }
 }
 
+static void *lwip_get_socket_select_semaphore()
+{
+    /* Calling this from the same process as select() will ensure that the semaphore won't be allocated from
+     * ISR (lwip_stop_socket_select_isr).
+     */
+    return (void *) sys_thread_sem_get();
+}
+
 static int lwip_fcntl_r_wrapper(int fd, int cmd, va_list args)
 {
     return lwip_fcntl_r(fd, cmd, va_arg(args, int));
@@ -61,6 +69,7 @@ void esp_vfs_lwip_sockets_register()
         .read = &lwip_read_r,
         .fcntl = &lwip_fcntl_r_wrapper,
         .ioctl = &lwip_ioctl_r_wrapper,
+        .get_socket_select_semaphore = &lwip_get_socket_select_semaphore,
         .socket_select = &lwip_select,
         .stop_socket_select = &lwip_stop_socket_select,
         .stop_socket_select_isr = &lwip_stop_socket_select_isr,
index 4d847274b4732097ebfb04e144e4b2dabdd26c06..ba7c89ab6ae721d0be9e920807bba0d346a8e36f 100644 (file)
@@ -187,6 +187,8 @@ typedef struct
     /** stop_socket_select which can be called from ISR; set only for the socket driver */
     void (*stop_socket_select_isr)(BaseType_t *woken);
     /** end_select is called to stop the I/O multiplexing and deinitialize the environment created by start_select for the given VFS */
+    void* (*get_socket_select_semaphore)();
+    /** get_socket_select_semaphore returns semaphore allocated in the socket driver; set only for the socket driver */
     void (*end_select)();
 } esp_vfs_t;
 
index a6ab14ca445326350d8aff52d4c9697ea4eaada3..584ca3c1f5e0e425029286d5a4d5e0373e1976cd 100644 (file)
@@ -838,6 +838,16 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
                         esp_vfs_safe_fd_isset(fd, errorfds)) {
                     const vfs_entry_t *vfs = s_vfs[vfs_index];
                     socket_select = vfs->vfs.socket_select;
+
+                    // get_socket_select_semaphore needs to be set for a socket driver where semaphore can be
+                    // initialized outside interrupt handlers (ignoring this could result in unexpected failures)
+                    if (vfs->vfs.get_socket_select_semaphore != NULL) {
+                        vfs->vfs.get_socket_select_semaphore(); // Semaphore is returned and it was allocated if it
+                        // wasn't before. We don't use the return value just need to be sure that it doesn't get
+                        // allocated later from ISR.
+                        // Note: ESP-IDF v4.0 will start to use this callback differently with some breaking changes
+                        // in the VFS API.
+                    }
                 }
             }
             continue;