open_coroutine_hook/
lib.rs1#![deny(
2 anonymous_parameters,
5 bare_trait_objects,
6 missing_copy_implementations,
8 missing_debug_implementations,
9 missing_docs, single_use_lifetimes, trivial_casts, trivial_numeric_casts,
13 unstable_features,
16 unused_extern_crates,
17 unused_import_braces,
18 unused_qualifications,
19 unused_results,
20 variant_size_differences,
21
22 warnings, clippy::all,
25 clippy::pedantic,
27 clippy::cargo,
29 unreachable_pub,
30)]
31#![allow(
32 clippy::blanket_clippy_restriction_lints, clippy::implicit_return, clippy::module_name_repetitions, clippy::multiple_crate_versions, clippy::missing_errors_doc, clippy::missing_panics_doc, clippy::panic_in_result_fn,
40 clippy::shadow_same, clippy::shadow_reuse, clippy::exhaustive_enums,
43 clippy::exhaustive_structs,
44 clippy::indexing_slicing,
45 clippy::separated_literal_suffix, clippy::single_char_lifetime_names, clippy::test_attr_in_doctest,
48 unknown_lints, linker_messages, )]
51#![doc = include_str!("../docs/en/hook.md")]
52
53use once_cell::sync::OnceCell;
54use open_coroutine_core::co_pool::task::UserTaskFunc;
55use open_coroutine_core::config::Config;
56use open_coroutine_core::net::join::JoinHandle;
57use open_coroutine_core::net::{EventLoops, UserFunc};
58use open_coroutine_core::scheduler::SchedulableCoroutine;
59use std::ffi::{c_int, c_longlong, c_uint};
60use std::time::Duration;
61
62static HOOK: OnceCell<bool> = OnceCell::new();
63
64pub(crate) fn hook() -> bool {
65 HOOK.get().map_or_else(|| false, |v| *v)
66}
67
68#[allow(
69 dead_code,
70 missing_docs,
71 clippy::similar_names,
72 clippy::not_unsafe_ptr_arg_deref,
73 clippy::many_single_char_names,
74 clippy::unnecessary_cast
75)]
76pub mod syscall;
77
78#[no_mangle]
80pub extern "C" fn open_coroutine_init(config: Config) -> c_int {
81 EventLoops::init(&config);
82 _ = HOOK.get_or_init(|| config.hook());
83 0
84}
85
86#[no_mangle]
88pub extern "C" fn open_coroutine_stop(secs: c_uint) -> c_int {
89 if EventLoops::stop(Duration::from_secs(u64::from(secs))).is_ok() {
90 return 0;
91 }
92 -1
93}
94
95#[no_mangle]
97pub extern "C" fn task_crate(f: UserTaskFunc, param: usize, priority: c_longlong) -> JoinHandle {
98 EventLoops::submit_task(
99 None,
100 move |p| Some(f(p.unwrap_or(0))),
101 Some(param),
102 Some(priority),
103 )
104}
105
106#[no_mangle]
108pub extern "C" fn task_cancel(handle: &JoinHandle) -> c_longlong {
109 match handle.get_name() {
110 Ok(name) => {
111 EventLoops::try_cancel_task(name);
112 0
113 }
114 Err(_) => -1,
115 }
116}
117
118#[no_mangle]
120pub extern "C" fn task_join(handle: &JoinHandle) -> c_longlong {
121 match handle.join() {
122 Ok(ptr) => match ptr {
123 Ok(ptr) => match ptr {
124 Some(ptr) => c_longlong::try_from(ptr).expect("overflow"),
125 None => 0,
126 },
127 Err(_) => -1,
128 },
129 Err(_) => -1,
130 }
131}
132
133#[no_mangle]
135pub extern "C" fn task_timeout_join(handle: &JoinHandle, ns_time: u64) -> c_longlong {
136 match handle.timeout_join(Duration::from_nanos(ns_time)) {
137 Ok(ptr) => match ptr {
138 Ok(ptr) => match ptr {
139 Some(ptr) => c_longlong::try_from(ptr).expect("overflow"),
140 None => 0,
141 },
142 Err(_) => -1,
143 },
144 Err(_) => -1,
145 }
146}
147
148#[no_mangle]
150pub extern "C" fn maybe_grow_stack(
151 red_zone: usize,
152 stack_size: usize,
153 f: UserFunc,
154 param: usize,
155) -> c_longlong {
156 let red_zone = if red_zone > 0 {
157 red_zone
158 } else {
159 open_coroutine_core::common::default_red_zone()
160 };
161 let stack_size = if stack_size > 0 {
162 stack_size
163 } else {
164 open_coroutine_core::common::constants::DEFAULT_STACK_SIZE
165 };
166 if let Ok(r) = SchedulableCoroutine::maybe_grow_with(red_zone, stack_size, || f(param)) {
167 return c_longlong::try_from(r).expect("overflow");
168 }
169 -1
170}