Dispatch returns a result envelope
dpm_execute fills a dpm_result on every call: status and error_code from the module's return value, and a payload the module hands back through dpm_set_result. The payload's layout belongs to the module and is documented per command; its release function is carried in the envelope and invoked by dpm_result_release. The context keeps a stack of the envelopes in progress, so a module calling a peer receives the peer's payload in its own envelope and its caller sees only what the module sets itself. The good fixture returns a payload and counts its releases, and the modules test covers the envelope fields, the payload round trip, single release, discard on a NULL envelope, and a payload set outside any dispatch. The prose documents describe the envelope and the payload header a module ships.
This commit is contained in:
@@ -70,13 +70,28 @@ dpm_get_module_info(ctx, mod, &info);
|
||||
|
||||
Deciding whether that version is suitable is yours. libdpm-core.so applies no version criterion of its own — a handle means the module is valid, not that it suits you.
|
||||
|
||||
`dpm_execute` invokes the module — a command name and arguments:
|
||||
`dpm_execute` invokes the module — a command name, arguments, and an envelope for the result:
|
||||
|
||||
```
|
||||
int rc = dpm_execute(ctx, mod, "command", argc, argv);
|
||||
dpm_result result;
|
||||
int rc = dpm_execute(ctx, mod, "command", argc, argv, &result);
|
||||
```
|
||||
|
||||
This is the only path into module code, and it is the same path the `dpm` binary uses and the same path a module uses to reach a peer. You address a module by name and a capability by command string, so your program compiles against no module header, no struct layout, and no module symbol. What a module accepts as commands and arguments, and what its return codes mean, is documented by that module.
|
||||
This is the only path into module code, and it is the same path the `dpm` binary uses and the same path a module uses to reach a peer. You address a module by name and a capability by command string. What a module accepts as commands and arguments, what its return codes mean, and what it returns as a payload, is documented by that module.
|
||||
|
||||
## Results
|
||||
|
||||
Every dispatch fills the envelope. `result.status` is `DPM_RESULT_OK` when the module returned 0 and `DPM_RESULT_ERROR` otherwise; `result.error_code` is the module's return value. Those two fields mean the same thing for every module and every command.
|
||||
|
||||
`result.data` is the payload: what the module returns for that command, in a layout the module documents for that command at that version. The module ships that layout as a header from its own repository, and your program includes it for the commands it reads. A module that returns nothing leaves `data` NULL.
|
||||
|
||||
The payload belongs to the module that produced it. When you are done with it:
|
||||
|
||||
```
|
||||
dpm_result_release(&result);
|
||||
```
|
||||
|
||||
That calls the release function the module supplied and clears `data`. Passing NULL as the envelope to `dpm_execute` discards the payload before the call returns, for a command whose result you do not need.
|
||||
|
||||
## Enumerating Modules
|
||||
|
||||
@@ -106,10 +121,12 @@ A name is recorded once. Adding one that is already an alias, or that belongs to
|
||||
- `dpm_get_resolved_module_path`(ctx) — the resolved module directory.
|
||||
- `dpm_set_last_error`(ctx, msg) — records a failure reason on the context; what a module calls to explain a nonzero return.
|
||||
- `dpm_get_last_error`(ctx) — a human-readable description of the most recent failure on the context, or NULL.
|
||||
- `dpm_set_result`(ctx, data, release) — hands a payload to the dispatch in progress; what a module calls to return data.
|
||||
- `dpm_result_release`(result) — releases a payload through the function the module supplied.
|
||||
|
||||
## Ownership and Errors
|
||||
|
||||
Strings returned by the library are owned by the context (or by the module that produced them) and remain valid until `dpm_close`; callers never free them. Functions returning int use 0 for success. Functions returning pointers use NULL for failure, with detail available from `dpm_get_last_error`.
|
||||
Strings returned by the library are owned by the context (or by the module that produced them) and remain valid until `dpm_close`; callers never free them. A payload in a `dpm_result` is owned by the module that produced it and is released with `dpm_result_release`. Functions returning int use 0 for success. Functions returning pointers use NULL for failure, with detail available from `dpm_get_last_error`.
|
||||
|
||||
## Complete Example
|
||||
|
||||
@@ -131,7 +148,9 @@ int main(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rc = dpm_execute(ctx, mod, "version", 0, NULL);
|
||||
dpm_result result;
|
||||
int rc = dpm_execute(ctx, mod, "version", 0, NULL, &result);
|
||||
dpm_result_release(&result);
|
||||
|
||||
dpm_close(ctx);
|
||||
return rc;
|
||||
|
||||
Reference in New Issue
Block a user