{"id":19203342,"url":"https://github.com/rouming/io","last_synced_at":"2025-07-09T04:34:32.957Z","repository":{"id":142055930,"uuid":"97004247","full_name":"rouming/io","owner":"rouming","description":"async IO library based on event loop + ZMTP (ZeroMQ) implementation","archived":false,"fork":false,"pushed_at":"2019-02-03T13:27:16.000Z","size":40,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-12T13:51:45.295Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rouming.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-12T12:20:43.000Z","updated_at":"2023-09-04T06:21:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"eee47a29-4842-4d0b-b9cc-575190a2e399","html_url":"https://github.com/rouming/io","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rouming/io","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rouming%2Fio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rouming%2Fio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rouming%2Fio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rouming%2Fio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rouming","download_url":"https://codeload.github.com/rouming/io/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rouming%2Fio/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264394660,"owners_count":23601342,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T12:47:56.987Z","updated_at":"2025-07-09T04:34:32.942Z","avatar_url":"https://github.com/rouming.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"io: async IO library based on event loop\n\nDescription:\n    Async IO library which is based on IO read/write requests, which can\n    be submitted to the IO queue and if file descriptor (socket, pipe,\n    whatever) is ready to perform read/write - completion will be called.\n\n    E.g. reads/writes from socket can be done as following:\n\n        struct io_queue q;\n        struct io_req req;\n        void *poller;\n        int err;\n\n        io_queue_init(\u0026q);\n\n        /* Create event loop poller */\n        err = poller_create(\u0026poller);\n        assert(err == 0);\n\n        /* Bind queue with one side of the socket */\n        err = io_queue_bind(\u0026q, poller, sock);\n        assert(err == 0);\n\n        /* Init read request, in case of completion on_read() will be called */\n        io_req_init(\u0026req, \u0026q, REQ_RD, NULL, on_read);\n        req.buf = (struct io_buf){\n            .iov[0] = {\n                .iov_base = NULL, /* buffer should be allocated */\n                .iov_len  = 10    /* want to read 10 bytes */\n            },\n            .iov_num  = 1,        /* we have only one buffer */\n            .is_vari_len = false  /* read exactly what is told, i.e. 10 bytes */\n        };\n\n        /* Submit request, i.e. put it to the submission list */\n        err = io_queue_submit(\u0026req);\n        assert(err == 0);\n\n        while (1) {\n            struct poller_item *items[16];\n            int i;\n\n            err = poller_wait(poller, items, ARRAY_SIZE(items), INT_MAX);\n            if (err == 0)\n                 continue;\n            else if (err \u003c 0) {\n                 printf(\"poller_wait() failed, errno=%d\\n\", -err);\n                 break;\n            }\n\n            /* Handle events */\n            for (i = 0; i \u003c err; i++) {\n                err = poller_do_action(poller, items[i]);\n                if (err)\n                    /* We are done. */\n                    break;\n            }\n        }\n\n        io_req_deinit(\u0026req);\n        io_queue_unbind(\u0026q);\n        poller_destroy(poller);\n\n\n    Exactly using the same pattern all other types of file descriptors can\n    be used.  See io-test.c for details, where signalfd is shown as example.\n\n    The nice thing about this is that any other protocol can be implemented\n    as a stack, e.g. zmtp-test.c accepts ZMTP (ZeroMQ) REQ sockets.\n\nWhy?\n    o No threads.\n    o No C++, no Java.\n    o Plain C.\n    o Single point of wait and control.\n    o Event driven.\n\nHowto:\n    $ make\n\n    then\n\n    $ ./io-test\n\n    or\n\n    $ ./zmtp-test\n\nAuthor:\n    Roman Pen \u003cr.peniaev@gmail.com\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frouming%2Fio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frouming%2Fio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frouming%2Fio/lists"}