{"id":19983046,"url":"https://github.com/madmurphy/libgnunetworker","last_synced_at":"2025-09-04T18:18:16.955Z","repository":{"id":86453856,"uuid":"451421632","full_name":"madmurphy/libgnunetworker","owner":"madmurphy","description":"Multithreading with GNUnet","archived":false,"fork":false,"pushed_at":"2025-03-22T18:30:27.000Z","size":308,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-02T20:02:34.080Z","etag":null,"topics":["c","event-loop","gnu","gnunet","library","multithreading","shared-library","threads","unix"],"latest_commit_sha":null,"homepage":"https://madmurphy.github.io/libgnunetworker","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/madmurphy.png","metadata":{"files":{"readme":"README","changelog":"ChangeLog","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-24T10:39:26.000Z","updated_at":"2025-03-22T15:22:08.000Z","dependencies_parsed_at":"2023-07-14T00:15:59.648Z","dependency_job_id":null,"html_url":"https://github.com/madmurphy/libgnunetworker","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/madmurphy/libgnunetworker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmurphy%2Flibgnunetworker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmurphy%2Flibgnunetworker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmurphy%2Flibgnunetworker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmurphy%2Flibgnunetworker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/madmurphy","download_url":"https://codeload.github.com/madmurphy/libgnunetworker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmurphy%2Flibgnunetworker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273651097,"owners_count":25143963,"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","status":"online","status_checked_at":"2025-09-04T02:00:08.968Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["c","event-loop","gnu","gnunet","library","multithreading","shared-library","threads","unix"],"created_at":"2024-11-13T04:13:58.890Z","updated_at":"2025-09-04T18:18:16.931Z","avatar_url":"https://github.com/madmurphy.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"GNUnet Worker Library\n=====================\n\nMultithreading with [**GNUnet**][1]\n\n\nOverview\n--------\n\n**GNUnet** is built following a single-threaded event-driven model, as it is\noften the case with network applications. This is an optimal model for dealing\nwith high concurrency scenarios, but can be problematic in other contexts\n(like, for example, graphical user interfaces, which normally have their own\nevent loop).\n\nTo accomplish its event-driven flow, **GNUnet** uses a scheduler. Once such a\nscheduler is started, it is not designed to be invoked by other threads, but\ncan schedule only routines requested by its own thread. What to do then if an\napplication needs to deal with multiple threads and let the latter interface\nwith **GNUnet**'s scheduler?\n\nThis framework offers a simple solution by creating a “bearing” between the\nthreads and the scheduler. The latter is run in its own dedicated thread and is\nunaware of the existence of other threads. Such a bearing consists in a “wish\nlist” of routines to schedule, which can be populated asynchronously by any\nthread and gets emptied synchronously only by the scheduler according to the\nlatter's natural flow.\n\nWhen using this framework, threads must never invoke **GNUnet**'s scheduler\ndirectly (preferably they must not even include `gnunet/gnunet_scheduler_lib.h`\nin their scope), and can only use `GNUNET_WORKER_push_load()` or\n`GNUNET_WORKER_push_load_with_priority()` to schedule new functions. They will\nalso have access to all the functions declared in `gnunet/gnunet_worker_lib.h`.\n\nThe functions scheduled in this way, on the other hand, will have full access\nto the **GNUnet** scheduler API and will follow its single-threaded\nevent-driven flow (indeed they will run in the scheduler's thread).\n\nUnder `examples/articulated-example` you can find an example of such division\nof labour, where `all-other-threads.c` launches multiple threads and\n`gnunet-thread.c` contains only functions that will run in the scheduler's\nthread.\n\nIf you want to know how to write **GTK** appplications using this library,\nplease check `examples/gtk4-example`.\n\n\nSimple example\n--------------\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cgnunet/gnunet_worker_lib.h\u003e\n\nstatic void task_for_the_scheduler (void * const data) {\n\n    printf(\"Hello world\\n\");\n\n}\n\nint main (const int argc, const char * const * const argv) {\n\n    GNUNET_WORKER_Handle my_worker;\n\n    /*  Create a separate thread where GNUnet's scheduler is run  */\n    if (GNUNET_WORKER_create(\u0026my_worker, NULL, NULL, NULL)) {\n\n        fprintf(stderr, \"Sorry, something went wrong :-(\\n\");\n        return 1;\n\n    };\n\n    /*  Run a function in the scheduler's thread  */\n    GNUNET_WORKER_push_load(\n        my_worker,\n        \u0026task_for_the_scheduler,\n        NULL\n    );\n\n    /*  Make sure that threads have had enough time to start...  */\n    sleep(1);\n\n    /*  Shut down the scheduler and wait until it returns  */\n    GNUNET_WORKER_synch_destroy(my_worker);\n\n    return 0;\n\n}\n```\n\nSee the `examples` subdirectory for further examples.\n\n\nA minimal tutorial\n------------------\n\nThere are three ways to create a **GNUnet** worker:\n\n1. `GNUNET_WORKER_create()`: **GNUnet**'s scheduler will be launched in a new\n   thread, equipped with a “load listener” for scheduling routines pushed by\n   other threads\n2. `GNUNET_WORKER_start_serving()`: the current thread will launch **GNUnet**'s\n   scheduler and equip it with a “load listener” for scheduling routines pushed\n   by other threads\n3. `GNUNET_WORKER_adopt_running_scheduler()`: this function assumes that\n   **GNUnet**'s scheduler is already running in the current thread (i.e. the\n   user has previously launched either `GNUNET_SCHEDULER_run()` or\n   `GNUNET_PROGRAM_run()`) and equipping the scheduler with a “load listener”\n   for scheduling routines pushed by other threads has become necessary\n\nAs soon as a handle for a new worker is made available, it is immediately\npossible to push load into it using `GNUNET_WORKER_push_load()` or\n`GNUNET_WORKER_push_load_with_priority()`. The routines added in this way will\nbe launched asynchronously in the worker's thread.\n\nThere are three ways for terminating a worker and shutting down its associated\n**GNUnet** scheduler:\n\n1. `GNUNET_WORKER_asynch_destroy()`: the worker will be terminated and its\n   memory freed, without waiting for the scheduler to complete the shutdown –\n   this will be completed in parallel (asynchronous)\n2. `GNUNET_WORKER_synch_destroy()`: the worker will be terminated and its\n   memory freed, waiting for the scheduler to complete the shutdown\n   (synchronous, “join”)\n3. `GNUNET_WORKER_timedsynch_destroy()`: the worker will be terminated and its\n   memory freed, waiting for the scheduler to complete the shutdown\n   (synchronous, “join”) only if this happens within a certain time, otherwise\n   it will be completed in parallel (asynchronous)\n\nIf a worker must be destroyed without shutting down its GNUnet scheduler, the\n`GNUNET_WORKER_dismiss()` function is available. The latter turns a worker back\ninto a “classic **GNUnet**'s scheduler” without any multithreading facility and\nwithout a “load listener”.\n\nAll the functions provided by this library can be safely launched by any thread\nat any moment.\n\nIf the documentation is missing and want to generate it, please make sure you\nhave **Doxygen** installed and then launch:\n\n```sh\n./configure\nmake redocs\n```\n\nFor any issue, [drop a message][2].\n\n\nCurrent limitations\n-------------------\n\nThe library is designed to be able to launch more than one scheduler at the\nsame time (i.e., repeated invocations of `GNUNET_WORKER_create()`), however the\nscheduler currently used by **GNUnet** is not thread-safe. Therefore, unless\nsomething changes in **GNUnet**'s code, `GNUNET_WORKER_create()` should be\ninvoked only once; or at least, it is necessary to make sure that a previous\nworker is always destroyed before invoking `GNUNET_WORKER_create()` again.\n\nThe library launches **GNUnet**'s scheduler using `GNUNET_SCHEDULER_run()`,\nwhich by default installs signal handlers, and installing signal handlers on a\nsecondary thread is rarely the way to go. The problem could be solved by making\nthe library rely on `GNUNET_SCHEDULER_run_with_optional_signals()` instead of\n`GNUNET_SCHEDULER_run()`, but the former function, despite being listed in\n`gnunet/gnunet_scheduler_lib.h`, has never been implemented.\n\n\nInstallation\n------------\n\nOn most Unix-like systems, you should be able to install this package using the\nfollowing common steps:\n\n```sh\n./configure\nmake\nmake install-strip\n```\n\nIf the `strip` utility is not available on your machine, use `make install`\ninstead (it will produce larger binaries).\n\nIf the `configure` script is missing from your package you need to generate it\nby running the `bootstrap` script. By default, `bootstrap` will also run the\n`configure` script immediately after having generated it, so you may type the\n`make` command directly after `bootstrap`. To list different options use\n`./bootstrap --help`.\n\nFor further information, see [INSTALL][3].\n\n\nDependencies\n------------\n\nThis library depends on the following packages:\n\n* pkg-config\n* gettext\n* gnunet\n\nPlease make sure that they are present before compiling the code.\n\n\nGet involved\n------------\n\nThis library needs help with internationalization. If a translation into your\nlanguage is missing and you wish to get involved, here is what to do.\n\nLet's say you want to create a Dutch translation of **libgnunetworker** (`nl`).\nFirst thing to do is to make sure that **GNU Autotools** and **GNU gettext**\nare installed on your system. Then clone this repository and launch the\nfollowing commands:\n\n``` sh\n./bootstrap\nmake -C po libgnunetworker.pot\n(cd po \u0026\u0026 msginit -l nl)\nmake bootstrap-clean \n```\n\nNow edit the `po/LINGUAS` file and add a new line containing the abbreviated\nname of the new language (`nl`).\n\nFinally, open the `po/nl.po` file and translate the strings present. All you\nhave to do now is to commit your changes.\n\n\nFree software\n-------------\n\n**GNUnet Worker** is free software. You can redistribute it and/or modify it\nunder the terms of the **AGPL** license version 3 or any later version. See\n[COPYING][4] for details.\n\n\n  [1]: https://www.gnunet.org/\n  [2]: https://github.com/madmurphy/libgnunetworker/issues\n  [3]: https://github.com/madmurphy/libgnunetworker/blob/main/INSTALL\n  [4]: https://github.com/madmurphy/libgnunetworker/blob/main/COPYING\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadmurphy%2Flibgnunetworker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmadmurphy%2Flibgnunetworker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadmurphy%2Flibgnunetworker/lists"}