/********************************************************************************************************* * ------------------------------------------------------------------------------------------------------ * file description * ------------------------------------------------------------------------------------------------------ * \file coroutine_io.h * \unit coroutine * \brief High-throughput asynchronous I/O multiplexer and cooperative socket API * \author Lamdonn * \version v0.2.0 * \license GPL-2.0 * \copyright Copyright (C) 2025 Lamdonn. ********************************************************************************************************/ #ifndef __coroutine_io_H #define __coroutine_io_H #include "coroutine.h" #include #include #ifdef __cplusplus extern "C" { #endif /* ======================================================================================================= * I/O Event Definitions * ======================================================================================================= */ #define CO_IO_READ (0x01) /**< Readable event */ #define CO_IO_WRITE (0x02) /**< Writable event */ #define CO_IO_ERROR (0x04) /**< Error or hangup event */ /* Return status codes */ #define CO_IO_OK (0) #define CO_IO_TIMEOUT (-1) #define CO_IO_ERROR_EVENT (-2) #define CO_IO_INVALID (-3) /* ======================================================================================================= * I/O Subsystem Management * ======================================================================================================= */ /** * \brief: Initialize coroutine I/O subsystem (e.g. socket library setup) * \return: 0 on success, or negative error code */ int CoIo_Init(void); /** * \brief: Deinitialize coroutine I/O subsystem */ void CoIo_Deinit(void); /** * \brief: Attach the high-throughput I/O poller to a specific scheduler * \param schedulerId: Target scheduler ID * \return: 0 on success, or negative error code * \note: Configures the scheduler's idleHook and wakeupHook to poll network descriptors and wake tasks instantly. */ int CoIo_AttachScheduler(uint32_t schedulerId); /** * \brief: Detach the I/O poller from a specific scheduler * \param schedulerId: Target scheduler ID * \return: 0 on success, or negative error code */ int CoIo_DetachScheduler(uint32_t schedulerId); /** * \brief: Set socket or file descriptor to non-blocking mode * \param fd: Descriptor handle * \return: 0 on success, or negative error code */ int CoIo_SetNonblocking(int fd); /** * \brief: Suspend current coroutine until descriptor fd has specified events or timeout * \param fd: Socket or file descriptor * \param events: Bitmask of CO_IO_READ / CO_IO_WRITE * \param timeoutMs: Timeout in milliseconds (0 for infinite) * \return: Ready events bitmask (>0) on success, CO_IO_TIMEOUT on timeout, or negative error code */ int CoTask_WaitFd(int fd, uint32_t events, uint32_t timeoutMs); /* ======================================================================================================= * Bare-Metal / MCU Poller Hook (Optional, for polling hardware UART, CAN, SPI without OS) * ======================================================================================================= */ typedef struct CoIoPollFd { int fd; /**< Device or descriptor handle (e.g. UART1, CAN1) */ short events; /**< Requested events (CO_IO_READ / CO_IO_WRITE) */ short revents; /**< Returned events */ } CoIoPollFd_t; /** * \brief: User-injected baremetal hardware poller callback * \param pfds: Array of descriptors and requested events * \param nfds: Number of descriptors * \param timeoutMs: Timeout in milliseconds * \return: Number of descriptors with events (>0), 0 on timeout, or negative error code */ typedef int (*CoIoBaremetalPoller_t)(CoIoPollFd_t *pfds, uint32_t nfds, int timeoutMs); /** * \brief: Register user-defined baremetal hardware poller (for MCU UART / CAN / SPI) * \param poller: Function pointer to poller callback, or NULL to reset */ void CoIo_SetBaremetalPoller(CoIoBaremetalPoller_t poller); /* ======================================================================================================= * High-Density Cooperative Socket APIs (Synchronous Code, Asynchronous Execution) * ======================================================================================================= */ /** * \brief: Create a non-blocking socket * \param domain: Address family (e.g. AF_INET) * \param type: Socket type (e.g. SOCK_STREAM, SOCK_DGRAM) * \param protocol: Protocol (e.g. 0 or IPPROTO_TCP) * \return: Non-blocking socket fd on success, or -1 on error */ int CoSocket_Create(int domain, int type, int protocol); /** * \brief: Connect to remote address with coroutine yield on wait * \param fd: Socket fd * \param addr: Pointer to struct sockaddr * \param addrlen: Size of addr * \param timeoutMs: Connection timeout in milliseconds * \return: 0 on success, or negative error code */ int CoSocket_Connect(int fd, const void *addr, int addrlen, uint32_t timeoutMs); /** * \brief: Accept an incoming connection with coroutine yield on wait * \param fd: Listening socket fd * \param addr: Output sockaddr pointer (optional, can be NULL) * \param addrlen: Input/output sockaddr len pointer (optional, can be NULL) * \param timeoutMs: Accept timeout in milliseconds * \return: Connected client socket fd (already non-blocking), or negative error code */ int CoSocket_Accept(int fd, void *addr, int *addrlen, uint32_t timeoutMs); /** * \brief: Read data from socket with coroutine yield on wait * \param fd: Connected socket fd * \param buf: Destination buffer * \param len: Buffer capacity * \param timeoutMs: Read timeout in milliseconds * \return: Bytes read (>0), 0 on EOF / connection closed, or negative error code */ int CoSocket_Read(int fd, void *buf, size_t len, uint32_t timeoutMs); /** * \brief: Write data to socket with coroutine yield on wait * \param fd: Connected socket fd * \param buf: Source buffer * \param len: Bytes to send * \param timeoutMs: Write timeout in milliseconds * \return: Bytes sent (>0), or negative error code */ int CoSocket_Write(int fd, const void *buf, size_t len, uint32_t timeoutMs); /** * \brief: Close a socket descriptor * \param fd: Socket fd * \return: 0 on success, or -1 on error */ int CoSocket_Close(int fd); #ifdef __cplusplus } #endif #endif /* !__coroutine_io_H */