From a5464f761adb08e905948d0b4e67d05e68cd7229 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Tue, 6 Apr 2021 14:46:14 -0700 Subject: [PATCH] chore(ffi): run gen_header.sh in CI environment (#2488) Clean up the script so that any unexpected error terminates the script, and stop suppressing errors that may contain useful information (for example, that you are using the stable version but need to use the nightly). This is useful because if hyper.h is not up to date going forward the CI should flag it. As is, there are a bunch of changes to hyper.h that have not been checked in (or were generated by a newer version of the cbindgen script.) Fixes #2483. --- .github/workflows/CI.yml | 40 ++++++- capi/cbindgen.toml | 6 + capi/gen_header.sh | 43 ++++--- capi/include/hyper.h | 250 +++++++++++++++++++++++++++------------ 4 files changed, 241 insertions(+), 98 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index ef8bcefda4..9ffd9f76f8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -17,6 +17,7 @@ jobs: - test - features - ffi + - ffi-header - doc steps: - run: exit 0 @@ -119,9 +120,7 @@ jobs: ffi: name: Test C API (FFI) needs: [style] - runs-on: ubuntu-latest - steps: - name: Checkout uses: actions/checkout@v1 @@ -147,10 +146,6 @@ jobs: command: build args: --features client,http1,http2,ffi - # TODO: re-enable check once figuring out how to get it working in CI - # - name: Verify cbindgen - # run: ./capi/gen_header.sh --verify - - name: Make Examples run: cd capi/examples && make client @@ -162,6 +157,39 @@ jobs: command: test args: --features full,ffi --lib + ffi-header: + name: Verify hyper.h is up to date + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v1 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + default: true + override: true + components: cargo + + - name: Install cbindgen + uses: actions-rs/cargo@v1 + with: + command: install + args: cbindgen + + - name: Build FFI + uses: actions-rs/cargo@v1 + env: + RUSTFLAGS: --cfg hyper_unstable_ffi + with: + command: build + args: --features client,http1,http2,ffi + + - name: Ensure that hyper.h is up to date + run: ./capi/gen_header.sh --verify + doc: name: Build docs needs: [style, test] diff --git a/capi/cbindgen.toml b/capi/cbindgen.toml index aef9c6237b..d1a58234b5 100644 --- a/capi/cbindgen.toml +++ b/capi/cbindgen.toml @@ -1,4 +1,10 @@ +# See https://github.com/eqrion/cbindgen/blob/master/docs.md#cbindgentoml for +# a list of possible configuration values. language = "C" +header = """/* + * Copyright 2021 Sean McArthur. MIT License. + * Generated by gen_header.sh. Do not edit directly. + */""" include_guard = "_HYPER_H" no_includes = true sys_includes = ["stdint.h", "stddef.h"] diff --git a/capi/gen_header.sh b/capi/gen_header.sh index 4cd1a26c23..a3a02e1c60 100755 --- a/capi/gen_header.sh +++ b/capi/gen_header.sh @@ -1,9 +1,13 @@ #!/usr/bin/env bash -CAPI_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +# This script regenerates hyper.h. As of April 2021, it only works with the +# nightly build of Rust. + +set -e -WORK_DIR=`mktemp -d` +CAPI_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +WORK_DIR=$(mktemp -d) # check if tmp dir was created if [[ ! "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then @@ -14,9 +18,8 @@ fi header_file_backup="$CAPI_DIR/include/hyper.h.backup" function cleanup { - #echo "$WORK_DIR" rm -rf "$WORK_DIR" - rm "$header_file_backup" + rm "$header_file_backup" || true } trap cleanup EXIT @@ -44,10 +47,14 @@ cp "$CAPI_DIR/include/hyper.h" "$header_file_backup" #cargo metadata --no-default-features --features ffi --format-version 1 > "$WORK_DIR/metadata.json" -cd $WORK_DIR +cd "${WORK_DIR}" || exit 2 # Expand just the ffi module -cargo rustc -- -Z unstable-options --pretty=expanded > expanded.rs 2>/dev/null +if ! output=$(cargo rustc -- -Z unstable-options --pretty=expanded 2>&1 > expanded.rs); then + # As of April 2021 the script above prints a lot of warnings/errors, and + # exits with a nonzero return code, but hyper.h still gets generated. + echo "$output" +fi # Replace the previous copy with the single expanded file rm -rf ./src @@ -56,17 +63,17 @@ mv expanded.rs src/lib.rs # Bindgen! -cbindgen\ - -c "$CAPI_DIR/cbindgen.toml"\ - --lockfile "$CAPI_DIR/../Cargo.lock"\ - -o "$CAPI_DIR/include/hyper.h"\ - $1 - -bindgen_exit_code=$? - -if [[ "--verify" == "$1" && "$bindgen_exit_code" != 0 ]]; then - echo "diff generated (<) vs backup (>)" - diff "$CAPI_DIR/include/hyper.h" "$header_file_backup" +if ! cbindgen \ + --config "$CAPI_DIR/cbindgen.toml" \ + --lockfile "$CAPI_DIR/../Cargo.lock" \ + --output "$CAPI_DIR/include/hyper.h" \ + "${@}"; then + bindgen_exit_code=$? + if [[ "--verify" == "$1" ]]; then + echo "diff generated (<) vs backup (>)" + diff "$CAPI_DIR/include/hyper.h" "$header_file_backup" + fi + exit $bindgen_exit_code fi -exit $bindgen_exit_code +exit 0 diff --git a/capi/include/hyper.h b/capi/include/hyper.h index cfc14a25fa..a305dc4a09 100644 --- a/capi/include/hyper.h +++ b/capi/include/hyper.h @@ -1,32 +1,78 @@ +/* + * Copyright 2021 Sean McArthur. MIT License. + * Generated by gen_header.sh. Do not edit directly. + */ + #ifndef _HYPER_H #define _HYPER_H #include #include +/* + Return in iter functions to continue iterating. + */ #define HYPER_ITER_CONTINUE 0 +/* + Return in iter functions to stop iterating. + */ #define HYPER_ITER_BREAK 1 +/* + An HTTP Version that is unspecified. + */ #define HYPER_HTTP_VERSION_NONE 0 +/* + The HTTP/1.0 version. + */ #define HYPER_HTTP_VERSION_1_0 10 +/* + The HTTP/1.1 version. + */ #define HYPER_HTTP_VERSION_1_1 11 +/* + The HTTP/2 version. + */ #define HYPER_HTTP_VERSION_2 20 +/* + Sentinel value to return from a read or write callback that the operation + is pending. + */ #define HYPER_IO_PENDING 4294967295 +/* + Sentinel value to return from a read or write callback that the operation + has errored. + */ #define HYPER_IO_ERROR 4294967294 +/* + Return in a poll function to indicate it was ready. + */ #define HYPER_POLL_READY 0 +/* + Return in a poll function to indicate it is still pending. + + The passed in `hyper_waker` should be registered to wake up the task at + some later point. + */ #define HYPER_POLL_PENDING 1 +/* + Return in a poll function indicate an error. + */ #define HYPER_POLL_ERROR 3 -typedef enum { +/* + A return code for many of hyper's methods. + */ +typedef enum hyper_code { /* All is well. */ @@ -60,7 +106,10 @@ typedef enum { HYPERE_INVALID_PEER_MESSAGE, } hyper_code; -typedef enum { +/* + A descriptor for what type a `hyper_task` value is. + */ +typedef enum hyper_task_return_type { /* The value of this task is null (does not imply an error). */ @@ -83,41 +132,86 @@ typedef enum { HYPER_TASK_BUF, } hyper_task_return_type; -typedef struct hyper_executor hyper_executor; - -typedef struct hyper_io hyper_io; - -typedef struct hyper_task hyper_task; - +/* + A streaming HTTP body. + */ typedef struct hyper_body hyper_body; +/* + A buffer of bytes that is sent or received on a `hyper_body`. + */ typedef struct hyper_buf hyper_buf; +/* + An HTTP client connection handle. + + These are used to send a request on a single connection. It's possible to + send multiple requests on a single connection, such as when HTTP/1 + keep-alive or HTTP/2 is used. + */ typedef struct hyper_clientconn hyper_clientconn; +/* + An options builder to configure an HTTP client connection. + */ typedef struct hyper_clientconn_options hyper_clientconn_options; +/* + An async context for a task that contains the related waker. + */ typedef struct hyper_context hyper_context; +/* + A more detailed error object returned by some hyper functions. + */ typedef struct hyper_error hyper_error; +/* + A task executor for `hyper_task`s. + */ +typedef struct hyper_executor hyper_executor; + +/* + An HTTP header map. + + These can be part of a request or response. + */ typedef struct hyper_headers hyper_headers; +/* + An IO object used to represent a socket or similar concept. + */ +typedef struct hyper_io hyper_io; + +/* + An HTTP request. + */ typedef struct hyper_request hyper_request; +/* + An HTTP response. + */ typedef struct hyper_response hyper_response; +/* + An async task. + */ +typedef struct hyper_task hyper_task; + +/* + A waker that is saved and used to waken a pending task. + */ typedef struct hyper_waker hyper_waker; -typedef int (*hyper_body_foreach_callback)(void*, const hyper_buf*); +typedef int (*hyper_body_foreach_callback)(void*, const struct hyper_buf*); -typedef int (*hyper_body_data_callback)(void*, hyper_context*, hyper_buf**); +typedef int (*hyper_body_data_callback)(void*, struct hyper_context*, struct hyper_buf**); typedef int (*hyper_headers_foreach_callback)(void*, const uint8_t*, size_t, const uint8_t*, size_t); -typedef size_t (*hyper_io_read_callback)(void*, hyper_context*, uint8_t*, size_t); +typedef size_t (*hyper_io_read_callback)(void*, struct hyper_context*, uint8_t*, size_t); -typedef size_t (*hyper_io_write_callback)(void*, hyper_context*, const uint8_t*, size_t); +typedef size_t (*hyper_io_write_callback)(void*, struct hyper_context*, const uint8_t*, size_t); #ifdef __cplusplus extern "C" { @@ -133,12 +227,12 @@ const char *hyper_version(void); If not configured, this body acts as an empty payload. */ -hyper_body *hyper_body_new(void); +struct hyper_body *hyper_body_new(void); /* Free a `hyper_body *`. */ -void hyper_body_free(hyper_body *body); +void hyper_body_free(struct hyper_body *body); /* Return a task that will poll the body for the next buffer of data. @@ -152,7 +246,7 @@ void hyper_body_free(hyper_body *body); This does not consume the `hyper_body *`, so it may be used to again. However, it MUST NOT be used or freed until the related task completes. */ -hyper_task *hyper_body_data(hyper_body *body); +struct hyper_task *hyper_body_data(struct hyper_body *body); /* Return a task that will poll the body and execute the callback with each @@ -166,12 +260,14 @@ hyper_task *hyper_body_data(hyper_body *body); This will consume the `hyper_body *`, you shouldn't use it anymore or free it. */ -hyper_task *hyper_body_foreach(hyper_body *body, hyper_body_foreach_callback func, void *userdata); +struct hyper_task *hyper_body_foreach(struct hyper_body *body, + hyper_body_foreach_callback func, + void *userdata); /* Set userdata on this body, which will be passed to callback functions. */ -void hyper_body_set_userdata(hyper_body *body, void *userdata); +void hyper_body_set_userdata(struct hyper_body *body, void *userdata); /* Set the data callback for this body. @@ -194,7 +290,7 @@ void hyper_body_set_userdata(hyper_body *body, void *userdata); If some error has occurred, you can return `HYPER_POLL_ERROR` to abort the body. */ -void hyper_body_set_data_func(hyper_body *body, hyper_body_data_callback func); +void hyper_body_set_data_func(struct hyper_body *body, hyper_body_data_callback func); /* Create a new `hyper_buf *` by copying the provided bytes. @@ -202,7 +298,7 @@ void hyper_body_set_data_func(hyper_body *body, hyper_body_data_callback func); This makes an owned copy of the bytes, so the `buf` argument can be freed or changed afterwards. */ -hyper_buf *hyper_buf_copy(const uint8_t *buf, size_t len); +struct hyper_buf *hyper_buf_copy(const uint8_t *buf, size_t len); /* Get a pointer to the bytes in this buffer. @@ -213,17 +309,17 @@ hyper_buf *hyper_buf_copy(const uint8_t *buf, size_t len); This pointer is borrowed data, and not valid once the `hyper_buf` is consumed/freed. */ -const uint8_t *hyper_buf_bytes(const hyper_buf *buf); +const uint8_t *hyper_buf_bytes(const struct hyper_buf *buf); /* Get the length of the bytes this buffer contains. */ -size_t hyper_buf_len(const hyper_buf *buf); +size_t hyper_buf_len(const struct hyper_buf *buf); /* Free this buffer. */ -void hyper_buf_free(hyper_buf *buf); +void hyper_buf_free(struct hyper_buf *buf); /* Starts an HTTP client connection handshake using the provided IO transport @@ -234,7 +330,8 @@ void hyper_buf_free(hyper_buf *buf); The returned `hyper_task *` must be polled with an executor until the handshake completes, at which point the value can be taken. */ -hyper_task *hyper_clientconn_handshake(hyper_io *io, hyper_clientconn_options *options); +struct hyper_task *hyper_clientconn_handshake(struct hyper_io *io, + struct hyper_clientconn_options *options); /* Send a request on the client connection. @@ -242,46 +339,47 @@ hyper_task *hyper_clientconn_handshake(hyper_io *io, hyper_clientconn_options *o Returns a task that needs to be polled until it is ready. When ready, the task yields a `hyper_response *`. */ -hyper_task *hyper_clientconn_send(hyper_clientconn *conn, hyper_request *req); +struct hyper_task *hyper_clientconn_send(struct hyper_clientconn *conn, struct hyper_request *req); /* Free a `hyper_clientconn *`. */ -void hyper_clientconn_free(hyper_clientconn *conn); +void hyper_clientconn_free(struct hyper_clientconn *conn); /* Creates a new set of HTTP clientconn options to be used in a handshake. */ -hyper_clientconn_options *hyper_clientconn_options_new(void); +struct hyper_clientconn_options *hyper_clientconn_options_new(void); /* Free a `hyper_clientconn_options *`. */ -void hyper_clientconn_options_free(hyper_clientconn_options *opts); +void hyper_clientconn_options_free(struct hyper_clientconn_options *opts); /* Set the client background task executor. This does not consume the `options` or the `exec`. */ -void hyper_clientconn_options_exec(hyper_clientconn_options *opts, const hyper_executor *exec); +void hyper_clientconn_options_exec(struct hyper_clientconn_options *opts, + const struct hyper_executor *exec); /* Set the whether to use HTTP2. Pass `0` to disable, `1` to enable. */ -hyper_code hyper_clientconn_options_http2(hyper_clientconn_options *opts, int enabled); +enum hyper_code hyper_clientconn_options_http2(struct hyper_clientconn_options *opts, int enabled); /* Frees a `hyper_error`. */ -void hyper_error_free(hyper_error *err); +void hyper_error_free(struct hyper_error *err); /* Get an equivalent `hyper_code` from this error. */ -hyper_code hyper_error_code(const hyper_error *err); +enum hyper_code hyper_error_code(const struct hyper_error *err); /* Print the details of this error to a buffer. @@ -291,27 +389,31 @@ hyper_code hyper_error_code(const hyper_error *err); The return value is number of bytes that were written to `dst`. */ -size_t hyper_error_print(const hyper_error *err, uint8_t *dst, size_t dst_len); +size_t hyper_error_print(const struct hyper_error *err, uint8_t *dst, size_t dst_len); /* Construct a new HTTP request. */ -hyper_request *hyper_request_new(void); +struct hyper_request *hyper_request_new(void); /* Free an HTTP request if not going to send it on a client. */ -void hyper_request_free(hyper_request *req); +void hyper_request_free(struct hyper_request *req); /* Set the HTTP Method of the request. */ -hyper_code hyper_request_set_method(hyper_request *req, const uint8_t *method, size_t method_len); +enum hyper_code hyper_request_set_method(struct hyper_request *req, + const uint8_t *method, + size_t method_len); /* Set the URI of the request. */ -hyper_code hyper_request_set_uri(hyper_request *req, const uint8_t *uri, size_t uri_len); +enum hyper_code hyper_request_set_uri(struct hyper_request *req, + const uint8_t *uri, + size_t uri_len); /* Set the preferred HTTP version of the request. @@ -321,7 +423,7 @@ hyper_code hyper_request_set_uri(hyper_request *req, const uint8_t *uri, size_t Note that this won't change the major HTTP version of the connection, since that is determined at the handshake step. */ -hyper_code hyper_request_set_version(hyper_request *req, int version); +enum hyper_code hyper_request_set_version(struct hyper_request *req, int version); /* Gets a reference to the HTTP headers of this request @@ -329,7 +431,7 @@ hyper_code hyper_request_set_version(hyper_request *req, int version); This is not an owned reference, so it should not be accessed after the `hyper_request` has been consumed. */ -hyper_headers *hyper_request_headers(hyper_request *req); +struct hyper_headers *hyper_request_headers(struct hyper_request *req); /* Set the body of the request. @@ -339,19 +441,19 @@ hyper_headers *hyper_request_headers(hyper_request *req); This takes ownership of the `hyper_body *`, you must not use it or free it after setting it on the request. */ -hyper_code hyper_request_set_body(hyper_request *req, hyper_body *body); +enum hyper_code hyper_request_set_body(struct hyper_request *req, struct hyper_body *body); /* Free an HTTP response after using it. */ -void hyper_response_free(hyper_response *resp); +void hyper_response_free(struct hyper_response *resp); /* Get the HTTP-Status code of this response. It will always be within the range of 100-599. */ -uint16_t hyper_response_status(const hyper_response *resp); +uint16_t hyper_response_status(const struct hyper_response *resp); /* Get a pointer to the reason-phrase of this response. @@ -364,14 +466,14 @@ uint16_t hyper_response_status(const hyper_response *resp); Use `hyper_response_reason_phrase_len()` to get the length of this buffer. */ -const uint8_t *hyper_response_reason_phrase(const hyper_response *resp); +const uint8_t *hyper_response_reason_phrase(const struct hyper_response *resp); /* Get the length of the reason-phrase of this response. Use `hyper_response_reason_phrase()` to get the buffer pointer. */ -size_t hyper_response_reason_phrase_len(const hyper_response *resp); +size_t hyper_response_reason_phrase_len(const struct hyper_response *resp); /* Get the HTTP version used by this response. @@ -383,7 +485,7 @@ size_t hyper_response_reason_phrase_len(const hyper_response *resp); - `HYPER_HTTP_VERSION_2` - `HYPER_HTTP_VERSION_NONE` if newer (or older). */ -int hyper_response_version(const hyper_response *resp); +int hyper_response_version(const struct hyper_response *resp); /* Gets a reference to the HTTP headers of this response. @@ -391,14 +493,14 @@ int hyper_response_version(const hyper_response *resp); This is not an owned reference, so it should not be accessed after the `hyper_response` has been freed. */ -hyper_headers *hyper_response_headers(hyper_response *resp); +struct hyper_headers *hyper_response_headers(struct hyper_response *resp); /* Take ownership of the body of this response. It is safe to free the response even after taking ownership of its body. */ -hyper_body *hyper_response_body(hyper_response *resp); +struct hyper_body *hyper_response_body(struct hyper_response *resp); /* Iterates the headers passing each name and value pair to the callback. @@ -408,7 +510,7 @@ hyper_body *hyper_response_body(hyper_response *resp); The callback should return `HYPER_ITER_CONTINUE` to keep iterating, or `HYPER_ITER_BREAK` to stop. */ -void hyper_headers_foreach(const hyper_headers *headers, +void hyper_headers_foreach(const struct hyper_headers *headers, hyper_headers_foreach_callback func, void *userdata); @@ -417,11 +519,11 @@ void hyper_headers_foreach(const hyper_headers *headers, This overwrites any previous value set for the header. */ -hyper_code hyper_headers_set(hyper_headers *headers, - const uint8_t *name, - size_t name_len, - const uint8_t *value, - size_t value_len); +enum hyper_code hyper_headers_set(struct hyper_headers *headers, + const uint8_t *name, + size_t name_len, + const uint8_t *value, + size_t value_len); /* Adds the provided value to the list of the provided name. @@ -429,11 +531,11 @@ hyper_code hyper_headers_set(hyper_headers *headers, If there were already existing values for the name, this will append the new value to the internal list. */ -hyper_code hyper_headers_add(hyper_headers *headers, - const uint8_t *name, - size_t name_len, - const uint8_t *value, - size_t value_len); +enum hyper_code hyper_headers_add(struct hyper_headers *headers, + const uint8_t *name, + size_t name_len, + const uint8_t *value, + size_t value_len); /* Create a new IO type used to represent a transport. @@ -441,7 +543,7 @@ hyper_code hyper_headers_add(hyper_headers *headers, The read and write functions of this transport should be set with `hyper_io_set_read` and `hyper_io_set_write`. */ -hyper_io *hyper_io_new(void); +struct hyper_io *hyper_io_new(void); /* Free an unused `hyper_io *`. @@ -449,14 +551,14 @@ hyper_io *hyper_io_new(void); This is typically only useful if you aren't going to pass ownership of the IO handle to hyper, such as with `hyper_clientconn_handshake()`. */ -void hyper_io_free(hyper_io *io); +void hyper_io_free(struct hyper_io *io); /* Set the user data pointer for this IO to some value. This value is passed as an argument to the read and write callbacks. */ -void hyper_io_set_userdata(hyper_io *io, void *data); +void hyper_io_set_userdata(struct hyper_io *io, void *data); /* Set the read function for this IO transport. @@ -476,7 +578,7 @@ void hyper_io_set_userdata(hyper_io *io, void *data); If there is an irrecoverable error reading data, then `HYPER_IO_ERROR` should be the return value. */ -void hyper_io_set_read(hyper_io *io, hyper_io_read_callback func); +void hyper_io_set_read(struct hyper_io *io, hyper_io_read_callback func); /* Set the write function for this IO transport. @@ -493,17 +595,17 @@ void hyper_io_set_read(hyper_io *io, hyper_io_read_callback func); If there is an irrecoverable error reading data, then `HYPER_IO_ERROR` should be the return value. */ -void hyper_io_set_write(hyper_io *io, hyper_io_write_callback func); +void hyper_io_set_write(struct hyper_io *io, hyper_io_write_callback func); /* Creates a new task executor. */ -const hyper_executor *hyper_executor_new(void); +const struct hyper_executor *hyper_executor_new(void); /* Frees an executor and any incomplete tasks still part of it. */ -void hyper_executor_free(const hyper_executor *exec); +void hyper_executor_free(const struct hyper_executor *exec); /* Push a task onto the executor. @@ -511,7 +613,7 @@ void hyper_executor_free(const hyper_executor *exec); The executor takes ownership of the task, it should not be accessed again unless returned back to the user with `hyper_executor_poll`. */ -hyper_code hyper_executor_push(const hyper_executor *exec, hyper_task *task); +enum hyper_code hyper_executor_push(const struct hyper_executor *exec, struct hyper_task *task); /* Polls the executor, trying to make progress on any tasks that have notified @@ -521,12 +623,12 @@ hyper_code hyper_executor_push(const hyper_executor *exec, hyper_task *task); If there are no ready tasks, this returns `NULL`. */ -hyper_task *hyper_executor_poll(const hyper_executor *exec); +struct hyper_task *hyper_executor_poll(const struct hyper_executor *exec); /* Free a task. */ -void hyper_task_free(hyper_task *task); +void hyper_task_free(struct hyper_task *task); /* Takes the output value of this task. @@ -536,12 +638,12 @@ void hyper_task_free(hyper_task *task); Use `hyper_task_type` to determine the type of the `void *` return value. */ -void *hyper_task_value(hyper_task *task); +void *hyper_task_value(struct hyper_task *task); /* Query the return type of this task. */ -hyper_task_return_type hyper_task_type(hyper_task *task); +enum hyper_task_return_type hyper_task_type(struct hyper_task *task); /* Set a user data pointer to be associated with this task. @@ -549,27 +651,27 @@ hyper_task_return_type hyper_task_type(hyper_task *task); This value will be passed to task callbacks, and can be checked later with `hyper_task_userdata`. */ -void hyper_task_set_userdata(hyper_task *task, void *userdata); +void hyper_task_set_userdata(struct hyper_task *task, void *userdata); /* Retrieve the userdata that has been set via `hyper_task_set_userdata`. */ -void *hyper_task_userdata(hyper_task *task); +void *hyper_task_userdata(struct hyper_task *task); /* Copies a waker out of the task context. */ -hyper_waker *hyper_context_waker(hyper_context *cx); +struct hyper_waker *hyper_context_waker(struct hyper_context *cx); /* Free a waker that hasn't been woken. */ -void hyper_waker_free(hyper_waker *waker); +void hyper_waker_free(struct hyper_waker *waker); /* Free a waker that hasn't been woken. */ -void hyper_waker_wake(hyper_waker *waker); +void hyper_waker_wake(struct hyper_waker *waker); #ifdef __cplusplus } // extern "C"