blob: b69601036712374aab561b27723e0b550a14e727 [file] [log] [blame]
// Copyright 2026 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "iree/async/primitive.h"
#if defined(IREE_ASYNC_HAVE_FD)
#include <errno.h>
#include <unistd.h>
#endif // IREE_ASYNC_HAVE_FD
#if defined(IREE_ASYNC_HAVE_WIN32_HANDLE)
#include <windows.h>
#endif // IREE_ASYNC_HAVE_WIN32_HANDLE
#if defined(IREE_ASYNC_HAVE_MACH_PORT)
#include <mach/mach.h>
#endif // IREE_ASYNC_HAVE_MACH_PORT
iree_status_t iree_async_primitive_dup(iree_async_primitive_t primitive,
iree_async_primitive_t* out_primitive) {
*out_primitive = iree_async_primitive_none();
switch (primitive.type) {
case IREE_ASYNC_PRIMITIVE_TYPE_NONE:
return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
"cannot duplicate a NONE primitive");
#if defined(IREE_ASYNC_HAVE_FD)
case IREE_ASYNC_PRIMITIVE_TYPE_FD: {
int new_fd = dup(primitive.value.fd);
if (IREE_UNLIKELY(new_fd == -1)) {
return iree_make_status(iree_status_code_from_errno(errno),
"dup(%d) failed", primitive.value.fd);
}
*out_primitive = iree_async_primitive_from_fd(new_fd);
return iree_ok_status();
}
#endif // IREE_ASYNC_HAVE_FD
#if defined(IREE_ASYNC_HAVE_WIN32_HANDLE)
case IREE_ASYNC_PRIMITIVE_TYPE_WIN32_HANDLE: {
HANDLE new_handle = NULL;
if (IREE_UNLIKELY(!DuplicateHandle(GetCurrentProcess(),
(HANDLE)primitive.value.win32_handle,
GetCurrentProcess(), &new_handle, 0,
FALSE, DUPLICATE_SAME_ACCESS))) {
return iree_make_status(
iree_status_code_from_win32_error(GetLastError()),
"DuplicateHandle failed");
}
*out_primitive =
iree_async_primitive_from_win32_handle((uintptr_t)new_handle);
return iree_ok_status();
}
#endif // IREE_ASYNC_HAVE_WIN32_HANDLE
#if defined(IREE_ASYNC_HAVE_MACH_PORT)
case IREE_ASYNC_PRIMITIVE_TYPE_MACH_PORT: {
// Increment the send right reference count. The caller gets an
// independent send right that must be deallocated separately.
kern_return_t kr = mach_port_mod_refs(
mach_task_self(), (mach_port_t)primitive.value.mach_port,
MACH_PORT_RIGHT_SEND, 1);
if (IREE_UNLIKELY(kr != KERN_SUCCESS)) {
return iree_make_status(IREE_STATUS_INTERNAL,
"mach_port_mod_refs failed (%d)", kr);
}
*out_primitive =
iree_async_primitive_from_mach_port(primitive.value.mach_port);
return iree_ok_status();
}
#endif // IREE_ASYNC_HAVE_MACH_PORT
default:
return iree_make_status(IREE_STATUS_UNIMPLEMENTED,
"unsupported primitive type %d for duplication",
(int)primitive.type);
}
}
void iree_async_primitive_close(iree_async_primitive_t* primitive) {
if (!primitive) return;
switch (primitive->type) {
case IREE_ASYNC_PRIMITIVE_TYPE_NONE:
break;
#if defined(IREE_ASYNC_HAVE_FD)
case IREE_ASYNC_PRIMITIVE_TYPE_FD:
close(primitive->value.fd);
break;
#endif // IREE_ASYNC_HAVE_FD
#if defined(IREE_ASYNC_HAVE_WIN32_HANDLE)
case IREE_ASYNC_PRIMITIVE_TYPE_WIN32_HANDLE:
CloseHandle((HANDLE)primitive->value.win32_handle);
break;
#endif // IREE_ASYNC_HAVE_WIN32_HANDLE
#if defined(IREE_ASYNC_HAVE_MACH_PORT)
case IREE_ASYNC_PRIMITIVE_TYPE_MACH_PORT:
mach_port_deallocate(mach_task_self(),
(mach_port_t)primitive->value.mach_port);
break;
#endif // IREE_ASYNC_HAVE_MACH_PORT
default:
break;
}
*primitive = iree_async_primitive_none();
}