Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: reimplement some C macros and inline functions #131

Merged
merged 2 commits into from
Feb 14, 2025

Conversation

bavshin-f5
Copy link
Member

@bavshin-f5 bavshin-f5 commented Feb 13, 2025

Almost complete set of the missing methods for ngx_queue_t and ngx_event_t.

  • No logs in the ngx_event_t code, because the logging infrastructure is not available from nginx-sys. Also, because ngx_event_ident is evil.
    Note that ngx_event_ident still lurks in the event loop C code and will be called on your event when you least expect it.
  • A simple test for the queue methods is implemented in a subset of Rust that I'm going to call "C with traits". It passes through cargo miri test, which maybe possibly means that it is a valid Rust code.
    In all likeliness, we'll have to continue fencing in all the queue operations with unsafe and addr_of_mut!.

@bavshin-f5 bavshin-f5 changed the title feat!: reimplement some C macros and inline functions, remove unnecessary Rust macros feat!: reimplement some C macros and inline functions Feb 13, 2025
Copy link
Contributor

@xeioex xeioex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update in async example seems missing.

diff --git a/examples/async.rs b/examples/async.rs
index ae27fec6..dcce2bba 100644
--- a/examples/async.rs
+++ b/examples/async.rs
@@ -8,7 +8,7 @@ use ngx::core;
 use ngx::ffi::{
     ngx_array_push, ngx_command_t, ngx_conf_t, ngx_cycle, ngx_event_t, ngx_http_core_module, ngx_http_core_run_phases,
     ngx_http_handler_pt, ngx_http_module_t, ngx_http_phases_NGX_HTTP_ACCESS_PHASE, ngx_http_request_t, ngx_int_t,
-    ngx_module_t, ngx_posted_events, ngx_queue_s, ngx_str_t, ngx_uint_t, NGX_CONF_TAKE1, NGX_HTTP_LOC_CONF,
+    ngx_module_t, ngx_post_event, ngx_posted_events, ngx_str_t, ngx_uint_t, NGX_CONF_TAKE1, NGX_HTTP_LOC_CONF,
     NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_MODULE,
 };
 use ngx::http::{self, HTTPModule, MergeConfigError};
@@ -112,7 +112,7 @@ unsafe extern "C" fn check_async_work_done(event: *mut ngx_event_t) {
         // this doesn't have have good performance but works as a simple thread-safe example and doesn't causes
         // segfault. The best method that provides both thread-safety and performance requires
         // an nginx patch.
-        post_event(event, addr_of_mut!(ngx_posted_events));
+        ngx_post_event(event, addr_of_mut!(ngx_posted_events));
     }
 }
 
@@ -128,20 +128,6 @@ struct EventData {
 unsafe impl Send for EventData {}
 unsafe impl Sync for EventData {}
 
-// same as ngx_post_event
-// source: https://github.com/nginx/ngx-rust/pull/31/files#diff-132330bb775bed17fb9990ec2b56e6c52e6a9e56d62f2114fade95e4decdba08R80-R90
-unsafe fn post_event(event: *mut ngx_event_t, queue: *mut ngx_queue_s) {
-    let event = &mut (*event);
-    if event.posted() == 0 {
-        event.set_posted(1);
-        // translated from ngx_queue_insert_tail macro
-        event.queue.prev = (*queue).prev;
-        (*event.queue.prev).next = &event.queue as *const _ as *mut _;
-        event.queue.next = queue;
-        (*queue).prev = &event.queue as *const _ as *mut _;
-    }
-}
-
 http_request_handler!(async_access_handler, |request: &mut http::Request| {
     let co = unsafe { request.get_module_loc_conf::<ModuleConfig>(&*addr_of!(ngx_http_async_module)) };
     let co = co.expect("module config is none");
@@ -184,7 +170,7 @@ http_request_handler!(async_access_handler, |request: &mut http::Request| {
         event.data = Arc::into_raw(event_data.clone()) as _;
         event.log = (*ngx_cycle).log;
 
-        post_event(event, addr_of_mut!(ngx_posted_events));
+        ngx_post_event(event, addr_of_mut!(ngx_posted_events));
     }
 
     ngx_log_debug_http!(request, "async module enabled: {}", co.enable);

Bindgen does not support functional macros or inline functions, so we
have to maintain a copy of the implementation of any such item we need
to use.

There are no safe wrappers, because all the operations here are unsafe
and unsound, unless used on the heap- or pool-allocated objects with
certain ownership constraints.
Bindgen does not support functional macros or inline functions, so we
have to maintain a copy of the implementation for any such item we need
to use.
Copy link
Contributor

@xeioex xeioex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@bavshin-f5 bavshin-f5 merged commit 3b1d0ee into nginx:master Feb 14, 2025
10 checks passed
@bavshin-f5 bavshin-f5 deleted the functional-macros branch February 14, 2025 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants