mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-05 16:09:24 +02:00
Added services/async.
This commit is contained in:
parent
8330f23d20
commit
0749dfd67f
@ -51,6 +51,7 @@ extern "C" {
|
||||
#include "switch/services/acc.h"
|
||||
#include "switch/services/apm.h"
|
||||
#include "switch/services/applet.h"
|
||||
#include "switch/services/async.h"
|
||||
#include "switch/services/audin.h"
|
||||
#include "switch/services/audout.h"
|
||||
#include "switch/services/audren.h"
|
||||
|
112
nx/include/switch/services/async.h
Normal file
112
nx/include/switch/services/async.h
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* @file async.h
|
||||
* @brief NS/NIM IAsync* IPC wrapper.
|
||||
* @author yellows8
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
#pragma once
|
||||
#include "../types.h"
|
||||
#include "../applets/error.h"
|
||||
#include "../kernel/event.h"
|
||||
|
||||
/// AsyncValue
|
||||
typedef struct {
|
||||
Service s; ///< IAsyncValue
|
||||
Event event; ///< Event with autoclear=false.
|
||||
} AsyncValue;
|
||||
|
||||
/// AsyncResult
|
||||
typedef struct {
|
||||
Service s; ///< IAsyncResult
|
||||
Event event; ///< Event with autoclear=false.
|
||||
} AsyncResult;
|
||||
|
||||
///@name IAsyncValue
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief Close a \ref AsyncValue.
|
||||
* @note When the object is initialized, this uses \ref asyncValueCancel then \ref asyncValueWait with timeout=U64_MAX.
|
||||
* @param a \ref AsyncValue
|
||||
*/
|
||||
void asyncValueClose(AsyncValue *a);
|
||||
|
||||
/**
|
||||
* @brief Waits for the async operation to finish using the specified timeout.
|
||||
* @param a \ref AsyncValue
|
||||
* @param[in] timeout Timeout in nanoseconds. U64_MAX for no timeout.
|
||||
*/
|
||||
Result asyncValueWait(AsyncValue *a, u64 timeout);
|
||||
|
||||
/**
|
||||
* @brief Gets the value size.
|
||||
* @param a \ref AsyncValue
|
||||
* @param[out] size Output size.
|
||||
*/
|
||||
Result asyncValueGetSize(AsyncValue *a, u64 *size);
|
||||
|
||||
/**
|
||||
* @brief Gets the value.
|
||||
* @note Prior to using the cmd, this uses \ref asyncResultWait with timeout=U64_MAX.
|
||||
* @param a \ref AsyncValue
|
||||
* @param[out] buffer Output buffer.
|
||||
* @param[in] size Output buffer size.
|
||||
*/
|
||||
Result asyncValueGet(AsyncValue *a, void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Cancels the async operation.
|
||||
* @note Used automatically by \ref asyncValueClose.
|
||||
* @param a \ref AsyncValue
|
||||
*/
|
||||
Result asyncValueCancel(AsyncValue *a);
|
||||
|
||||
/**
|
||||
* @brief Gets the \ref ErrorContext.
|
||||
* @param a \ref AsyncValue
|
||||
* @param[out] context \ref ErrorContext
|
||||
*/
|
||||
Result asyncValueGetErrorContext(AsyncValue *a, ErrorContext *context);
|
||||
|
||||
///@}
|
||||
|
||||
///@name IAsyncResult
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief Close a \ref AsyncResult.
|
||||
* @note When the object is initialized, this uses \ref asyncResultCancel then \ref asyncResultWait with timeout=U64_MAX.
|
||||
* @param a \ref AsyncResult
|
||||
*/
|
||||
void asyncResultClose(AsyncResult *a);
|
||||
|
||||
/**
|
||||
* @brief Waits for the async operation to finish using the specified timeout.
|
||||
* @param a \ref AsyncResult
|
||||
* @param[in] timeout Timeout in nanoseconds. U64_MAX for no timeout.
|
||||
*/
|
||||
Result asyncResultWait(AsyncResult *a, u64 timeout);
|
||||
|
||||
/**
|
||||
* @brief Gets the Result.
|
||||
* @note Prior to using the cmd, this uses \ref asyncResultWait with timeout=U64_MAX.
|
||||
* @param a \ref AsyncResult
|
||||
*/
|
||||
Result asyncResultGet(AsyncResult *a);
|
||||
|
||||
/**
|
||||
* @brief Cancels the async operation.
|
||||
* @note Used automatically by \ref asyncResultClose.
|
||||
* @param a \ref AsyncResult
|
||||
*/
|
||||
Result asyncResultCancel(AsyncResult *a);
|
||||
|
||||
/**
|
||||
* @brief Gets the \ref ErrorContext.
|
||||
* @param a \ref AsyncResult
|
||||
* @param[out] context \ref ErrorContext
|
||||
*/
|
||||
Result asyncResultGetErrorContext(AsyncResult *a, ErrorContext *context);
|
||||
|
||||
///@}
|
||||
|
115
nx/source/services/async.c
Normal file
115
nx/source/services/async.c
Normal file
@ -0,0 +1,115 @@
|
||||
#include "sf/service.h"
|
||||
#include "runtime/hosversion.h"
|
||||
#include "services/async.h"
|
||||
#include "applets/error.h"
|
||||
|
||||
static Result _asyncCmdNoIO(Service* srv, u32 cmd_id) {
|
||||
return serviceDispatch(srv, cmd_id);
|
||||
}
|
||||
|
||||
static Result _asyncCmdNoInOutU64(Service* srv, u64 *out, u32 cmd_id) {
|
||||
return serviceDispatchOut(srv, cmd_id, *out);
|
||||
}
|
||||
|
||||
static Result _asyncCmdNoInOutBuf(Service* srv, void* buffer, size_t size, u32 cmd_id) {
|
||||
return serviceDispatch(srv, cmd_id,
|
||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||
.buffers = { { buffer, size } },
|
||||
);
|
||||
}
|
||||
|
||||
// IAsyncValue
|
||||
|
||||
void asyncValueClose(AsyncValue *a) {
|
||||
if (serviceIsActive(&a->s)) {
|
||||
asyncValueCancel(a); // Official sw ignores rc from this prior to waiting on the event.
|
||||
asyncValueWait(a, U64_MAX);
|
||||
}
|
||||
|
||||
serviceClose(&a->s);
|
||||
eventClose(&a->event);
|
||||
}
|
||||
|
||||
Result asyncValueWait(AsyncValue *a, u64 timeout) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return eventWait(&a->event, timeout);
|
||||
}
|
||||
|
||||
Result asyncValueGetSize(AsyncValue *a, u64 *size) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _asyncCmdNoInOutU64(&a->s, size, 0);
|
||||
}
|
||||
|
||||
Result asyncValueGet(AsyncValue *a, void* buffer, size_t size) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
Result rc = asyncValueWait(a, U64_MAX);
|
||||
if (R_SUCCEEDED(rc)) rc = _asyncCmdNoInOutBuf(&a->s, buffer, size, 1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result asyncValueCancel(AsyncValue *a) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _asyncCmdNoIO(&a->s, 2);
|
||||
}
|
||||
|
||||
Result asyncValueGetErrorContext(AsyncValue *a, ErrorContext *context) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (hosversionBefore(4,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _asyncCmdNoInOutBuf(&a->s, context, sizeof(*context), 3);
|
||||
}
|
||||
|
||||
// AsyncResult
|
||||
|
||||
void asyncResultClose(AsyncResult *a) {
|
||||
if (serviceIsActive(&a->s)) {
|
||||
asyncResultCancel(a); // Official sw ignores rc from this prior to waiting on the event.
|
||||
asyncResultWait(a, U64_MAX);
|
||||
}
|
||||
|
||||
serviceClose(&a->s);
|
||||
eventClose(&a->event);
|
||||
}
|
||||
|
||||
Result asyncResultWait(AsyncResult *a, u64 timeout) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return eventWait(&a->event, timeout);
|
||||
}
|
||||
|
||||
Result asyncResultGet(AsyncResult *a) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
Result rc = asyncResultWait(a, U64_MAX);
|
||||
if (R_SUCCEEDED(rc)) rc = _asyncCmdNoIO(&a->s, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result asyncResultCancel(AsyncResult *a) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _asyncCmdNoIO(&a->s, 1);
|
||||
}
|
||||
|
||||
Result asyncResultGetErrorContext(AsyncResult *a, ErrorContext *context) {
|
||||
if (!serviceIsActive(&a->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (hosversionBefore(4,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _asyncCmdNoInOutBuf(&a->s, context, sizeof(*context), 2);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user