1+ mod request;
2+ mod response;
3+ mod gvl_helpers;
4+
5+ use request:: Request ;
6+ use response:: Response ;
7+ use gvl_helpers:: nogvl;
8+
19use magnus:: block:: block_proc;
210use magnus:: r_hash:: ForEach ;
311use magnus:: typed_data:: Obj ;
4- use magnus:: value:: { qnil, Opaque } ;
5- use magnus:: { function, gc, method, prelude:: * , DataTypeFunctions , Error as MagnusError , RString , Ruby , TypedData , Value } ;
12+ use magnus:: { function, method, prelude:: * , Error as MagnusError , Ruby , Value } ;
613use bytes:: Bytes ;
714
8- use std:: { ffi:: c_void, mem:: MaybeUninit , ptr:: null_mut} ;
9-
10- use rb_sys:: rb_thread_call_without_gvl;
11-
1215use warp:: Filter ;
1316use warp:: http:: Response as WarpResponse ;
1417use std:: cell:: RefCell ;
@@ -35,84 +38,13 @@ impl ServerConfig {
3538 }
3639}
3740
41+ // Sent on the work channel with the request, and a oneshot channel to send the response back on.
3842struct RequestWithCompletion {
3943 request : Request ,
4044 // sent a response back on this thread
4145 response_tx : oneshot:: Sender < WarpResponse < Bytes > > ,
4246}
4347
44- // Request type that will be sent to worker threads
45- #[ derive( Debug ) ]
46- #[ magnus:: wrap( class = "HyperRuby::Request" ) ]
47- struct Request {
48- method : warp:: http:: Method ,
49- path : String ,
50- headers : warp:: http:: HeaderMap ,
51- body : Bytes ,
52- }
53-
54- impl Request {
55- pub fn method ( & self ) -> String {
56- self . method . to_string ( )
57- }
58-
59- pub fn path ( & self ) -> RString {
60- RString :: new ( & self . path )
61- }
62-
63- pub fn header ( & self , key : String ) -> Value {
64- match self . headers . get ( key) {
65- Some ( value) => match value. to_str ( ) {
66- Ok ( value) => RString :: new ( value) . as_value ( ) ,
67- Err ( _) => qnil ( ) . as_value ( ) ,
68- } ,
69- None => qnil ( ) . as_value ( ) ,
70- }
71- }
72-
73- pub fn body_size ( & self ) -> usize {
74- self . body . len ( )
75- }
76-
77- pub fn body ( & self ) -> Value {
78- if self . body . is_empty ( ) {
79- return qnil ( ) . as_value ( ) ;
80- }
81-
82- let result = RString :: buf_new ( self . body_size ( ) ) ;
83-
84- // cat to the end of the string directly from the byte buffer
85- result. cat ( self . body . as_ref ( ) ) ;
86- result. as_value ( )
87- }
88- }
89-
90-
91- #[ derive( TypedData ) ]
92- #[ magnus( class = "HyperRuby::Response" , mark) ]
93- struct Response {
94- status : u16 ,
95- headers : Opaque < magnus:: RHash > ,
96- body : Opaque < magnus:: RString > ,
97- }
98-
99- impl DataTypeFunctions for Response {
100- fn mark ( & self , marker : & gc:: Marker ) {
101- marker. mark ( self . headers ) ;
102- marker. mark ( self . body ) ;
103- }
104- }
105-
106- impl Response {
107- pub fn new ( status : u16 , headers : magnus:: RHash , body : RString ) -> Self {
108- Self {
109- status,
110- headers : headers. into ( ) ,
111- body : body. into ( ) ,
112- }
113- }
114- }
115-
11648#[ magnus:: wrap( class = "HyperRuby::Server" ) ]
11749struct Server {
11850 server_handle : Arc < Mutex < Option < JoinHandle < ( ) > > > > ,
@@ -121,30 +53,6 @@ struct Server {
12153 work_tx : RefCell < Option < Arc < crossbeam_channel:: Sender < RequestWithCompletion > > > > ,
12254}
12355
124-
125- pub ( crate ) fn nogvl < F , R > ( mut func : F ) -> R
126- where
127- F : FnMut ( ) -> R ,
128- R : Sized ,
129- {
130- unsafe extern "C" fn call_without_gvl < F , R > ( arg : * mut c_void ) -> * mut c_void
131- where
132- F : FnMut ( ) -> R ,
133- R : Sized ,
134- {
135- let arg = arg as * mut ( & mut F , & mut MaybeUninit < R > ) ;
136- let ( func, result) = unsafe { & mut * arg } ;
137- result. write ( func ( ) ) ;
138- null_mut ( )
139- }
140- let result = MaybeUninit :: uninit ( ) ;
141- let arg_ptr = & ( & mut func, & result) as * const _ as * mut c_void ;
142- unsafe {
143- rb_thread_call_without_gvl ( Some ( call_without_gvl :: < F , R > ) , arg_ptr, None , null_mut ( ) ) ;
144- result. assume_init ( )
145- }
146- }
147-
14856impl Server {
14957 pub fn new ( ) -> Self {
15058 let ( work_tx, work_rx) = crossbeam_channel:: bounded ( 1000 ) ;
0 commit comments