| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- /*
- * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <pthread.h>
- #include "esp_err.h"
- #include "errno.h"
- /** This module addresses the FreeRTOS simulator's coexistence with linux system calls from user apps.
- * It's only included when building without lwIP, so we need to use linux system's select() which would receive
- * EINTR event on every FreeRTOS interrupt; we workaround this problem by wrapping select()
- * to bypass and silence these events.
- */
- extern int __real_select (int fd, fd_set * rfds, fd_set * wfds, fd_set *efds, struct timeval *tval);
- static inline int64_t get_us(void)
- {
- struct timespec spec;
- clock_gettime(CLOCK_REALTIME, &spec);
- return spec.tv_nsec / 1000 + spec.tv_sec * 1000000;
- }
- int __wrap_select (int fd, fd_set * rfds, fd_set * wfds, fd_set *efds, struct timeval *tval)
- {
- int ret;
- struct timeval *tv = tval;
- struct timeval timeval_local = {};
- int64_t start = 0;
- int64_t timeout_us = 0;
- if (tv != NULL) {
- start = get_us();
- timeout_us = tval->tv_sec * 1000000 + tval->tv_usec;
- timeval_local.tv_sec = tval->tv_sec;
- timeval_local.tv_usec = tval->tv_usec;
- tv = &timeval_local; // this (tv != NULL) indicates that we should handle timeouts
- }
- while ((ret = __real_select(fd, rfds, wfds, efds, tv)) < 0 && errno == EINTR) {
- if (tv != NULL) {
- int64_t now = get_us();
- timeout_us -= now - start;
- if (timeout_us < 0) {
- errno = 0;
- ret = 0;
- break;
- }
- start = now;
- tv->tv_usec = timeout_us % 1000000;
- tv->tv_sec = timeout_us / 1000000;
- }
- }
- return ret;
- }
|