# How to Integrate libfiber with a MySQL Driver Without Modifying the Source Code

> Integrate libfiber with MySQL driver effortlessly. Run libmysqlclient code in coroutines without source code modification. Optimize your database interactions.

- Repository: [iQIYI/libfiber](https://github.com/iqiyi/libfiber)
- Tags: how-to-guide
- Published: 2026-03-04

---

**libfiber intercepts POSIX socket calls used by the MySQL C client library, allowing you to run standard `libmysqlclient` code inside coroutines without recompiling or patching the driver.**

The `iqiyi/libfiber` library provides a transparent API hooking mechanism that converts blocking network I/O into fiber-aware operations. Because the official MySQL C client (`libmysqlclient`) relies exclusively on standard POSIX networking APIs, you can achieve high-concurrency database access by wrapping existing MySQL code in libfiber coroutines. This integration requires zero changes to the MySQL driver source code or build process.

## How libfiber Intercepts MySQL I/O Without Code Changes

libfiber works by hooking standard POSIX networking APIs at runtime. When you initialize the library, system calls such as `socket`, `connect`, `read`, `write`, `select`, `poll`, and `epoll` are automatically replaced with coroutine-aware implementations.

In [`c/src/hook/socket.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/hook/socket.c), libfiber provides hooked versions of `socket()`, `connect()`, `accept()`, and `close()`. The MySQL driver uses these functions to establish and manage TCP connections to the database server. Similarly, [`c/src/hook/fiber_read.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/hook/fiber_read.c) and [`c/src/hook/write.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/hook/write.c) intercept the `read()` and `write()` families of calls that `libmysqlclient` uses to send queries and retrieve results.

Because these hooks operate at the system call layer, the MySQL driver continues to execute its original logic while libfiber transparently converts blocking operations into non-blocking events. The fiber scheduler in [`c/src/fiber.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/fiber.c) then multiplexes these events across the coroutine pool, enabling thousands of concurrent MySQL connections without thread overhead.

## Step-by-Step Integration Guide

### Initialize the libfiber Scheduler

Before executing any MySQL functions, initialize the fiber runtime. On Linux, call `acl_fiber_schedule_init(0)` to prepare the kernel-mode event mechanism (epoll/kqueue). On Windows, you must additionally enable WinAPI hooking via `winapi_hook()`.

```c
#include "fiber/lib_fiber.h"

int main(void) {
    /* Initialize kernel-mode event handling (epoll on Linux, IOCP on Windows) */
    acl_fiber_schedule_init(0);
    
    /* Windows-specific: enable WinAPI hooking */
    /* winapi_hook(); */
    
    return 0;
}

```

### Wrap MySQL Operations in a Fiber

Use `acl_fiber_create()` to spawn a coroutine that executes your standard MySQL client code. Inside the fiber, blocking calls like `mysql_real_connect()` and `mysql_query()` become non-blocking yield points. The scheduler automatically switches to other ready fibers while waiting for network events.

```c
static void mysql_fiber(ACL_FIBER *fb, void *ctx) {
    MYSQL *conn = mysql_init(NULL);
    
    /* This connect operation will be hooked and yield control */
    if (!mysql_real_connect(conn, "127.0.0.1", "user", "pass", 
                            "db", 3306, NULL, 0)) {
        /* handle error */
    }
    
    /* Query execution also becomes non-blocking */
    mysql_query(conn, "SELECT NOW()");
    /* process results... */
    mysql_close(conn);
}

```

### Start the Event Loop

After creating all fibers, invoke `acl_fiber_schedule_with(event_mode)` to run the event loop. This function drives the scheduler until all fibers complete.

```c
int main(void) {
    acl_fiber_schedule_init(0);
    
    /* Create fiber with 128KB stack */
    acl_fiber_create(mysql_fiber, NULL, 128 * 1024);
    
    /* Start the scheduler - blocks until all fibers exit */
    acl_fiber_schedule_with(FIBER_EVENT_KERNEL);
    return 0;
}

```

### Control Concurrency with Semaphores

To prevent overwhelming the database server, use fiber-aware semaphores defined in [`c/src/sync/fiber_sem.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/sync/fiber_sem.c). The `acl_fiber_sem_wait()` and `acl_fiber_sem_signal()` functions allow you to limit concurrent connections without blocking the entire thread.

```c
ACL_FIBER_SEM *sem = acl_fiber_sem_create(100); /* Max 100 concurrent */

static void limited_mysql_fiber(ACL_FIBER *fb, void *ctx) {
    acl_fiber_sem_wait(sem);
    
    /* MySQL operations here */
    
    acl_fiber_sem_signal(sem);
}

```

## Complete C Integration Example

The following example compiles against the standard MySQL client library without modifications. The fiber wrapper in [`patch.h`](https://github.com/iqiyi/libfiber/blob/main/patch.h) (typically provided in libfiber examples) supplies the necessary socket wrappers, though the hooks work automatically once the scheduler initializes.

```c
/* Build: gcc -o mysql_fiber mysql_fiber.c -lfiber -lmysqlclient -lpthread -ldl */

#include <stdio.h>
#include <stdlib.h>
#include <mysql.h>
#include "fiber/lib_fiber.h"

static void mysql_fiber(ACL_FIBER *fb, void *ctx)
{
    (void) fb;
    (void) ctx;

    MYSQL *conn = mysql_init(NULL);
    if (!conn) {
        fprintf(stderr, "mysql_init failed\n");
        return;
    }

    /* Hooked connect - yields instead of blocking */
    if (!mysql_real_connect(conn, "127.0.0.1", "user", "passwd",
                            "testdb", 3306, NULL, 0)) {
        fprintf(stderr, "connect error: %s\n", mysql_error(conn));
        mysql_close(conn);
        return;
    }

    /* Hooked send/recv operations */
    if (mysql_query(conn, "SELECT NOW()")) {
        fprintf(stderr, "query error: %s\n", mysql_error(conn));
        mysql_close(conn);
        return;
    }

    MYSQL_RES *res = mysql_store_result(conn);
    if (res) {
        MYSQL_ROW row = mysql_fetch_row(res);
        if (row) printf("Server time: %s\n", row[0]);
        mysql_free_result(res);
    }

    mysql_close(conn);
}

int main(void)
{
    int event_mode = FIBER_EVENT_KERNEL;
    acl_fiber_schedule_init(0);

    const size_t stack_size = 128 * 1024;
    acl_fiber_create(mysql_fiber, NULL, stack_size);

    acl_fiber_schedule_with(event_mode);
    return 0;
}

```

## C++ Integration Using the libfiber Wrapper

For C++ applications, libfiber provides a modern wrapper that simplifies fiber creation. The [`go_fiber.hpp`](https://github.com/iqiyi/libfiber/blob/main/go_fiber.hpp) header enables lambda-based coroutine spawning while maintaining the same transparent hooking of MySQL I/O.

```cpp
// Build: g++ -std=c++11 -o mysql_fiber mysql_fiber.cpp -lfiber -lmysqlclient -lpthread -ldl

#include <mysql.h>
#include <acl-lib/fiber/libfiber.hpp>
#include <acl-lib/fiber/go_fiber.hpp>

static void mysql_task(int id)
{
    MYSQL *conn = mysql_init(nullptr);
    if (!conn) return;

    if (!mysql_real_connect(conn, "127.0.0.1", "user", "passwd",
                            "testdb", 3306, nullptr, 0)) {
        mysql_close(conn);
        return;
    }

    if (mysql_query(conn, "SELECT NOW()")) {
        mysql_close(conn);
        return;
    }

    MYSQL_RES *res = mysql_store_result(conn);
    if (res) {
        MYSQL_ROW row = mysql_fetch_row(res);
        if (row) printf("Task %d: Server time: %s\n", id, row[0]);
        mysql_free_result(res);
    }
    mysql_close(conn);
}

int main()
{
    int event_mode = FIBER_EVENT_KERNEL;
    acl::fiber::schedule_init();

    /* Launch multiple MySQL coroutines */
    for (int i = 0; i < 10; ++i) {
        go[=] { mysql_task(i); };
    }

    acl::fiber::schedule(event_mode);
    return 0;
}

```

## Key Source Files Behind the Hook Mechanism

Understanding the following files in the `iqiyi/libfiber` repository helps diagnose integration issues and optimize performance:

- **[`c/src/hook/socket.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/hook/socket.c)** – Implements hooked versions of `socket()`, `connect()`, `accept()`, and `close()`. These are the primary entry points the MySQL driver uses for TCP connection management.

- **[`c/src/hook/fiber_read.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/hook/fiber_read.c)** and **[`c/src/hook/write.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/hook/write.c)** – Provide fiber-aware implementations of `read()`, `write()`, `recv()`, and `send()`. MySQL's protocol layer depends on these for query transmission and result retrieval.

- **[`c/src/hook/poll.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/hook/poll.c)** – Hooks `poll()`, `select()`, and `epoll_wait()` so the MySQL driver's readiness checks integrate with the fiber scheduler's event loop.

- **[`c/src/hook/getaddrinfo.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/hook/getaddrinfo.c)** – Intercepts DNS resolution calls to prevent blocking name lookups from freezing the fiber scheduler.

- **[`c/src/fiber.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/fiber.c)** – Contains the core scheduler implementation including `acl_fiber_schedule_init()` and `acl_fiber_schedule_with()`.

- **[`c/src/sync/fiber_sem.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/sync/fiber_sem.c)** – Implements the semaphore API (`acl_fiber_sem_create()`, `acl_fiber_sem_wait()`, `acl_fiber_sem_signal()`) for limiting concurrent database connections.

## Summary

- **libfiber hooks POSIX socket APIs** at runtime, making the MySQL driver's blocking calls yield control to the fiber scheduler automatically.
- **No driver modifications required** – compile against standard `libmysqlclient` and link with `-lfiber`.
- **Initialize before use** – call `acl_fiber_schedule_init()` before creating fibers, then `acl_fiber_schedule_with()` to start the event loop.
- **Wrap MySQL logic** in fibers using `acl_fiber_create()` (C) or the `go` lambda wrapper (C++).
- **Control resource usage** with fiber-aware semaphores from [`c/src/sync/fiber_sem.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/sync/fiber_sem.c) to limit concurrent connections.

## Frequently Asked Questions

### Does libfiber require recompiling libmysqlclient?

No. libfiber operates through API hooking at the system call layer. The MySQL client library continues to use standard `socket()`, `connect()`, and `read()` calls, but libfiber intercepts these in [`c/src/hook/socket.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/hook/socket.c) and related files, converting them into non-blocking operations. Link your application with `-lfiber` alongside `-lmysqlclient` without changing the MySQL build.

### Which system calls does libfiber hook for MySQL compatibility?

According to the source in `c/src/hook/`, libfiber hooks `socket()`, `connect()`, `accept()`, `close()`, `read()`, `write()`, `poll()`, `select()`, `epoll_wait()`, and `getaddrinfo()`. These cover all network I/O paths used by `libmysqlclient` for connection establishment, query execution, and result fetching.

### How does libfiber handle DNS resolution in MySQL connections?

The file [`c/src/hook/getaddrinfo.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/hook/getaddrinfo.c) provides a hooked implementation of `getaddrinfo()` and related name resolution functions. When `mysql_real_connect()` performs a DNS lookup, the hooked version registers the resolution request with the fiber scheduler, yielding control until the name lookup completes, preventing the entire thread from blocking.

### Can I limit concurrent MySQL connections when using libfiber?

Yes. Use the semaphore API implemented in [`c/src/sync/fiber_sem.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/sync/fiber_sem.c). Create a semaphore with `acl_fiber_sem_create(max_connections)`, then wrap your MySQL connection logic with `acl_fiber_sem_wait()` before connecting and `acl_fiber_sem_signal()` after disconnecting. This limits simultaneous database connections while keeping the fiber scheduler responsive.