88
99extern  crate  alloc; 
1010
11+ use  alloc:: boxed:: Box ; 
1112use  alloc:: vec:: Vec ; 
1213use  alloc:: vec; 
1314use  alloc:: string:: String ; 
1415use  alloc:: string:: ToString ; 
16+ use  alloc:: ffi:: CString ; 
17+ 
1518use  core:: alloc:: { GlobalAlloc ,  Layout } ; 
19+ use  core:: cell:: Cell ; 
20+ use  core:: cell:: RefCell ; 
1621use  core:: ffi:: c_char; 
1722use  core:: ffi:: c_int; 
1823use  core:: ffi:: c_void; 
19- use  core:: fmt:: { self ,  Arguments ,  Write } ; 
20- 
21- use  alloc:: ffi:: CString ; 
2224use  core:: ffi:: CStr ; 
23- use  core:: panic :: PanicInfo ; 
25+ use  core:: fmt :: { self ,   Arguments ,   Write } ; 
2426use  core:: num:: TryFromIntError ; 
27+ use  core:: panic:: PanicInfo ; 
2528
2629#[ unsafe( link_section = ".module_license" ) ]  
2730pub  static  LICENSE :  [ u8 ;  15 ]  = * b"LICENSE=GPLv3+\0 " ; 
@@ -363,11 +366,9 @@ pub struct Command {
363366    cmd :  * mut  GrubCommand , 
364367} 
365368
366- static  mut  commands:  Vec < Command >  = vec ! [ ] ; 
367- 
368369impl  Command  { 
369370    pub  fn  register ( name :  & str ,  cb :  fn  ( argv :  & [ & str ] )  -> Result < ( ) ,  GrubError > , 
370- 		    summary :  & str ,  description :  & str )  { 
371+ 		    summary :  & str ,  description :  & str )  ->  Self   { 
371372	let  mut  ret = Command  { 
372373	    name :  CString :: new ( name) . unwrap ( ) , 
373374	    summary :  CString :: new ( summary) . unwrap ( ) , 
@@ -381,15 +382,15 @@ impl Command {
381382						  ret. description . as_ptr ( ) , 
382383						  0 ) ; 
383384	    ( * ret. cmd ) . data  = cb as  * mut  c_void ; 
384- 	    commands. push ( ret) ; 
385385	} 
386+ 	return  ret; 
386387    } 
388+ } 
387389
388-     pub  fn  unregister_all ( )  { 
390+ impl  Drop  for  Command  { 
391+     fn  drop ( & mut  self )  { 
389392	unsafe  { 
390- 	    for  cmd in  commands. iter ( )  { 
391- 		grub_unregister_command ( cmd. cmd ) ; 
392- 	    } 
393+ 	    grub_unregister_command ( self . cmd ) ; 
393394	} 
394395    } 
395396} 
@@ -470,3 +471,58 @@ impl Drop for File {
470471	unsafe  {  grub_file_close ( self . file ) ;  } 
471472    } 
472473} 
474+ 
475+ pub  trait  ModuleFini  { 
476+     fn  module_fini ( & self ) ; 
477+ } 
478+ 
479+ pub  struct  ModuleCell < T >  { 
480+     inner :  Cell < Option < T > > , 
481+ } 
482+ 
483+ pub  struct  ModuleRefHolder  { 
484+     val :  Cell < * const  c_void > , 
485+     destructors :  RefCell < Vec < Box < dyn  ModuleFini > > > , 
486+ } 
487+ 
488+ impl < T >  ModuleCell < T >  { 
489+     pub  fn  set ( & ' static  self ,  dl :  & ModuleRefHolder ,  value :  T )  { 
490+ 	self . inner . set ( Some ( value) ) ; 
491+ 	dl. destructors . borrow_mut ( ) . push ( Box :: new ( self ) ) ; 
492+     } 
493+ 
494+     pub  const  fn  new ( )  -> Self  { 
495+ 	Self { inner :  Cell :: new ( None ) } 
496+     } 
497+ } 
498+ 
499+ impl < T >  ModuleFini  for  & ModuleCell < T >  { 
500+     fn  module_fini ( & self )  { 
501+ 	self . inner . set ( None ) ; 
502+     } 
503+ } 
504+ 
505+ // SAFETY: We're single-threaded with disabled interrupts 
506+ unsafe  impl < T >  Sync  for  ModuleCell < T >  { 
507+ } 
508+ 
509+ impl  ModuleRefHolder  { 
510+     pub  fn  init ( & self ,  value :  * const  c_void )  { 
511+ 	self . val . set ( value) ; 
512+     } 
513+ 
514+     pub  fn  fini ( & self )  { 
515+ 	for  d in  self . destructors . borrow ( ) . iter ( )  { 
516+ 	    d. module_fini ( ) ; 
517+ 	} 
518+ 	self . destructors . borrow_mut ( ) . clear ( ) ; 
519+     } 
520+ 
521+     pub  const  fn  new ( )  -> Self  { 
522+ 	Self { val :  Cell :: new ( core:: ptr:: null ( ) ) ,  destructors :  RefCell :: new ( vec ! [ ] ) } 
523+     } 
524+ } 
525+ 
526+ // SAFETY: We're single-threaded with disabled interrupts 
527+ unsafe  impl  Sync  for  ModuleRefHolder  { 
528+ } 
0 commit comments