@@ -31,6 +31,7 @@ use hyperion_vfs::{
31
31
path:: Path ,
32
32
tree:: { FileRef , Node } ,
33
33
} ;
34
+ use lock_api:: ArcMutexGuard ;
34
35
use time:: Duration ;
35
36
use x86_64:: { structures:: paging:: PageTableFlags , VirtAddr } ;
36
37
@@ -242,39 +243,6 @@ pub fn pfree(args: &mut SyscallRegs) -> Result<usize> {
242
243
return Ok ( 0 ) ;
243
244
}
244
245
245
- /// send data to an input channel of a process
246
- ///
247
- /// # arguments
248
- /// - `syscall_id` : 11
249
- /// - `arg0` : target PID
250
- /// - `arg1` : data ptr
251
- /// - `arg2` : data len (bytes)
252
- pub fn send ( args : & mut SyscallRegs ) -> Result < usize > {
253
- let target_pid = args. arg0 ;
254
- let data = read_untrusted_bytes ( args. arg1 , args. arg2 ) ?;
255
-
256
- let pid = hyperion_scheduler:: task:: Pid :: new ( target_pid as usize ) ;
257
-
258
- if hyperion_scheduler:: send ( pid, data) . is_err ( ) {
259
- return Err ( Error :: NO_SUCH_PROCESS ) ;
260
- }
261
-
262
- return Ok ( 0 ) ;
263
- }
264
-
265
- /// recv data from this process input channel
266
- ///
267
- /// returns the number of bytes read
268
- ///
269
- /// # arguments
270
- /// - `syscall_id` : 12
271
- /// - `arg0` : data ptr
272
- /// - `arg1` : data len (bytes)
273
- pub fn recv ( args : & mut SyscallRegs ) -> Result < usize > {
274
- let buf = read_untrusted_bytes_mut ( args. arg0 , args. arg1 ) ?;
275
- return Ok ( hyperion_scheduler:: recv ( buf) ) ;
276
- }
277
-
278
246
/// rename the current process
279
247
///
280
248
/// # arguments
@@ -503,24 +471,16 @@ fn _bind(socket: SocketDesc, addr: &str) -> Result<()> {
503
471
return Err ( Error :: NOT_FOUND ) ;
504
472
} ;
505
473
506
- let this = process ( ) ;
507
- let ext = process_ext_with ( & this) ;
474
+ let socket = get_socket ( socket) ?;
508
475
509
- let sockets = ext. sockets . lock ( ) ;
510
- let socket_file = sockets
511
- . get ( socket. 0 )
512
- . and_then ( |s| s. as_ref ( ) )
513
- . ok_or ( Error :: BAD_FILE_DESCRIPTOR ) ?
514
- . socket_ref
515
- . clone ( ) ;
516
- drop ( sockets) ;
517
-
518
- let dir = VFS_ROOT
476
+ VFS_ROOT
477
+ // find the directory node
519
478
. find_dir ( dir, false )
520
- . map_err ( map_vfs_err_to_syscall_err) ?;
521
-
522
- dir. lock ( )
523
- . create_node ( sock_file, Node :: File ( socket_file) )
479
+ . map_err ( map_vfs_err_to_syscall_err) ?
480
+ // lock the directory
481
+ . lock_arc ( )
482
+ // create the socket file in that directory
483
+ . create_node ( sock_file, Node :: File ( socket) )
524
484
. map_err ( map_vfs_err_to_syscall_err) ?;
525
485
526
486
return Ok ( ( ) ) ;
@@ -535,17 +495,9 @@ fn listen(args: &mut SyscallRegs) -> Result<usize> {
535
495
}
536
496
537
497
fn _listen ( socket : SocketDesc ) -> Result < ( ) > {
538
- let this = process ( ) ;
539
- let ext = process_ext_with ( & this) ;
540
-
541
- ext. sockets
542
- . lock ( )
543
- . get ( socket. 0 )
544
- . and_then ( |s| s. as_ref ( ) )
545
- . ok_or ( Error :: BAD_FILE_DESCRIPTOR ) ?
546
- . socket_ref
547
- . lock ( )
548
- . conn = Some ( Arc :: new ( Channel :: new ( ) ) ) ;
498
+ get_socket_locked ( socket) ?
499
+ . conn
500
+ . get_or_insert_with ( || Arc :: new ( Channel :: new ( ) ) ) ;
549
501
550
502
Ok ( ( ) )
551
503
}
@@ -560,19 +512,7 @@ fn accept(args: &mut SyscallRegs) -> Result<usize> {
560
512
}
561
513
562
514
fn _accept ( socket : SocketDesc ) -> Result < SocketDesc > {
563
- let this = process ( ) ;
564
- let ext = process_ext_with ( & this) ;
565
-
566
- let sockets = ext. sockets . lock ( ) ;
567
- let socket = sockets
568
- . get ( socket. 0 )
569
- . and_then ( |s| s. as_ref ( ) )
570
- . ok_or ( Error :: BAD_FILE_DESCRIPTOR ) ?
571
- . socket_ref
572
- . clone ( ) ;
573
- drop ( sockets) ;
574
-
575
- let mut socket = socket. lock ( ) ;
515
+ let mut socket = get_socket_locked ( socket) ?;
576
516
577
517
let domain = socket. domain ;
578
518
let ty = socket. ty ;
@@ -609,22 +549,13 @@ fn connect(args: &mut SyscallRegs) -> Result<usize> {
609
549
}
610
550
611
551
fn _connect ( socket : SocketDesc , addr : & str ) -> Result < ( ) > {
612
- let this = process ( ) ;
613
- let ext = process_ext_with ( & this) ;
614
-
615
- let sockets = ext. sockets . lock ( ) ;
616
- let client = sockets
617
- . get ( socket. 0 )
618
- . and_then ( |s| s. as_ref ( ) )
619
- . ok_or ( Error :: BAD_FILE_DESCRIPTOR ) ?
620
- . socket_ref
621
- . clone ( ) ;
622
- drop ( sockets) ;
552
+ // get the client socket early to test for errors, but lock it late
553
+ let client = get_socket ( socket) ?;
623
554
624
555
let server = VFS_ROOT
625
556
. find_file ( addr, false , false )
626
- . map_err ( map_vfs_err_to_syscall_err) ?;
627
- let server = server . lock ( ) ;
557
+ . map_err ( map_vfs_err_to_syscall_err) ?
558
+ . lock_arc ( ) ;
628
559
629
560
// TODO: inode
630
561
let conn = server
@@ -642,13 +573,62 @@ fn _connect(socket: SocketDesc, addr: &str) -> Result<()> {
642
573
drop ( server) ;
643
574
644
575
let pipe = Arc :: new ( Pipe :: new ( ) ) ;
645
- conn. send ( pipe. clone ( ) ) ;
646
-
647
- client. lock ( ) . pipe = Some ( pipe) ;
576
+ client. lock ( ) . pipe = Some ( pipe. clone ( ) ) ;
577
+ conn. send ( pipe) ;
648
578
649
579
Ok ( ( ) )
650
580
}
651
581
582
+ /// send data to a socket
583
+ ///
584
+ /// [`hyperion_syscall::send`]
585
+ pub fn send ( args : & mut SyscallRegs ) -> Result < usize > {
586
+ let socket = SocketDesc ( args. arg0 as _ ) ;
587
+ let data = read_untrusted_bytes ( args. arg1 , args. arg2 ) ?;
588
+ let flags = args. arg3 as _ ;
589
+
590
+ _send ( socket, data, flags) . map ( |_| 0 )
591
+ }
592
+
593
+ fn _send ( socket : SocketDesc , data : & [ u8 ] , _flags : usize ) -> Result < ( ) > {
594
+ let socket = get_socket_locked ( socket) ?;
595
+
596
+ let Some ( pipe) = socket. pipe . as_ref ( ) . cloned ( ) else {
597
+ return Err ( Error :: BAD_FILE_DESCRIPTOR ) ;
598
+ } ;
599
+
600
+ drop ( socket) ;
601
+
602
+ pipe. send_slice ( data) ;
603
+
604
+ return Ok ( ( ) ) ;
605
+ }
606
+
607
+ /// recv data from a socket
608
+ ///
609
+ /// [`hyperion_syscall::recv`]
610
+ pub fn recv ( args : & mut SyscallRegs ) -> Result < usize > {
611
+ let socket = SocketDesc ( args. arg0 as _ ) ;
612
+ let buf = read_untrusted_bytes_mut ( args. arg1 , args. arg2 ) ?;
613
+ let flags = args. arg3 as _ ;
614
+
615
+ _recv ( socket, buf, flags)
616
+ }
617
+
618
+ fn _recv ( socket : SocketDesc , buf : & mut [ u8 ] , _flags : usize ) -> Result < usize > {
619
+ let socket = get_socket_locked ( socket) ?;
620
+
621
+ let Some ( pipe) = socket. pipe . as_ref ( ) . cloned ( ) else {
622
+ return Err ( Error :: BAD_FILE_DESCRIPTOR ) ;
623
+ } ;
624
+
625
+ drop ( socket) ;
626
+
627
+ let bytes = pipe. recv_slice ( buf) ;
628
+
629
+ return Ok ( bytes) ;
630
+ }
631
+
652
632
//
653
633
654
634
struct ProcessExtra {
@@ -711,6 +691,26 @@ impl ProcessExt for ProcessExtra {
711
691
712
692
//
713
693
694
+ fn get_socket_locked ( socket : SocketDesc ) -> Result < ArcMutexGuard < Futex , SocketFile > > {
695
+ get_socket ( socket) . map ( |v| v. lock_arc ( ) )
696
+ }
697
+
698
+ fn get_socket ( socket : SocketDesc ) -> Result < Arc < Mutex < SocketFile > > > {
699
+ let this = process ( ) ;
700
+ let ext = process_ext_with ( & this) ;
701
+
702
+ let socket = ext
703
+ . sockets
704
+ . lock ( )
705
+ . get ( socket. 0 )
706
+ . and_then ( |s| s. as_ref ( ) )
707
+ . ok_or ( Error :: BAD_FILE_DESCRIPTOR ) ?
708
+ . socket_ref
709
+ . clone ( ) ;
710
+
711
+ Ok ( socket)
712
+ }
713
+
714
714
fn process_ext_with ( proc : & Process ) -> & ProcessExtra {
715
715
proc. ext
716
716
. call_once ( || {
0 commit comments