{"id":16923768,"url":"https://github.com/bugaevc/c_yield","last_synced_at":"2025-03-21T00:29:49.043Z","repository":{"id":71726565,"uuid":"94653396","full_name":"bugaevc/c_yield","owner":"bugaevc","description":"A simple stackful coroutines implementation in C with a few demos","archived":false,"fork":false,"pushed_at":"2017-06-17T22:55:19.000Z","size":4,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-25T21:11:57.445Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/bugaevc.png","metadata":{"files":{"readme":"README.md","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-06-17T22:54:10.000Z","updated_at":"2017-06-17T22:55:20.000Z","dependencies_parsed_at":"2023-03-15T15:30:43.770Z","dependency_job_id":null,"html_url":"https://github.com/bugaevc/c_yield","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bugaevc%2Fc_yield","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bugaevc%2Fc_yield/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bugaevc%2Fc_yield/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bugaevc%2Fc_yield/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bugaevc","download_url":"https://codeload.github.com/bugaevc/c_yield/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244716866,"owners_count":20498276,"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-10-13T20:00:34.233Z","updated_at":"2025-03-21T00:29:49.023Z","avatar_url":"https://github.com/bugaevc.png","language":"C","readme":"# Writing generators\n\nThe first thing the generator does should be calling `gen_init()`, storing the\nreturned value (generator handle).\n\nReturn type of the function should be declared as `gen_t *`. To actually return,\ndo `gen_return(handle, val); return handle;`. Never exit the generator without\ncalling `gen_return()`, even if there's no important value to pass.\n\nTo yield, call `gen_yield(handle, val)`. The call returns the value sent via\n`gen_send()`, so make sure to save it if it's important.\n\n# Calling generators\n\nCall the generator as a usual function. It won't do anything immediately, but\nreturn the handle you will use to control it.\n\nInteract with the generator by calling `gen_send(handle, val)`. The value you\nsend will be returned inside the generator from `gen_yield()`, whereas the value\nthat the generator yields next time will be returned from the `gen_send()` call.\nNote: the first call of `gen_send()` has no corresponding `gen_yield()` call to\nreturn value from, so the value you pass will be silently discarded.\n\nWhen the generator returns, the return value is passed as the result of\n`gen_send()` in the same way that yielded values are. Use `gen_is_done()` to\ndistinguish between yielded and return values. After the generator returns, call\n`free()` on the handle.\n\n# Notes\n\nIt should work fine to pass handles around and call `gen_*()` on them from\nsomewhat unexpected places (ex. yield the value from a generator from inside\nsome other generator that was called by the first one). However, generator\ninvocations are not reentrant, that is, you should not call `gen_yield()` on a\nhandle twice without a `gen_send()` call on the same handle in between, and vice\nversa.\n\nAll `gen_*()` functions are thread-safe.\n\nAs `gen_return()` function never returns, putting `return handle;` after it is\nmerely a convention, doubled as a way to silence the compiler warning about not\nreturning a `gen_t *` value.\n\nAs you could see by reading the source code, `gen_send()` and `gen_yield()` are\nactually the same function. What it does is it dumps the state, switches to the\nother stack, loads the state saved there and returns the value it got passed in\nthe first place.\n\nWe tried hard to make generators debug-friendly. In particular, we display the\noriginal generator call in the call stack, rather than the place `gen_send()`\nwas called (especially useful in coroutines running on an event loop).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbugaevc%2Fc_yield","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbugaevc%2Fc_yield","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbugaevc%2Fc_yield/lists"}