@@ -666,6 +666,104 @@ static umf_result_t os_allocation_merge(void *provider, void *lowPtr,
666666    return  UMF_RESULT_SUCCESS ;
667667}
668668
669+ typedef  struct  os_ipc_data_t  {
670+     int  pid ;
671+     int  fd ;
672+     size_t  fd_offset ;
673+     size_t  size ;
674+ } os_ipc_data_t ;
675+ 
676+ static  umf_result_t  os_get_ipc_handle_size (void  * provider , size_t  * size ) {
677+     if  (provider  ==  NULL  ||  size  ==  NULL ) {
678+         return  UMF_RESULT_ERROR_INVALID_ARGUMENT ;
679+     }
680+ 
681+     * size  =  sizeof (os_ipc_data_t );
682+     return  UMF_RESULT_SUCCESS ;
683+ }
684+ 
685+ static  umf_result_t  os_get_ipc_handle (void  * provider , const  void  * ptr ,
686+                                       size_t  size , void  * providerIpcData ) {
687+     if  (provider  ==  NULL  ||  providerIpcData  ==  NULL ) {
688+         return  UMF_RESULT_ERROR_INVALID_ARGUMENT ;
689+     }
690+ 
691+     os_memory_provider_t  * os_provider  =  (os_memory_provider_t  * )provider ;
692+ 
693+     void  * value  =  critnib_get (os_provider -> ptr_off , (uintptr_t )ptr );
694+     if  (value  ==  NULL ) {
695+         return  UMF_RESULT_ERROR_INVALID_ARGUMENT ;
696+     }
697+ 
698+     os_ipc_data_t  * os_ipc_data  =  (os_ipc_data_t  * )providerIpcData ;
699+     os_ipc_data -> pid  =  os_getpid ();
700+     os_ipc_data -> fd  =  os_provider -> fd ;
701+     os_ipc_data -> fd_offset  =  (size_t )value ;
702+     os_ipc_data -> size  =  size ;
703+ 
704+     return  UMF_RESULT_SUCCESS ;
705+ }
706+ 
707+ static  umf_result_t  os_put_ipc_handle (void  * provider , void  * providerIpcData ) {
708+     if  (provider  ==  NULL  ||  providerIpcData  ==  NULL ) {
709+         return  UMF_RESULT_ERROR_INVALID_ARGUMENT ;
710+     }
711+ 
712+     os_memory_provider_t  * os_provider  =  (os_memory_provider_t  * )provider ;
713+     os_ipc_data_t  * os_ipc_data  =  (os_ipc_data_t  * )providerIpcData ;
714+ 
715+     if  (os_ipc_data -> fd  !=  os_provider -> fd  ||  os_ipc_data -> pid  !=  os_getpid ()) {
716+         return  UMF_RESULT_ERROR_INVALID_ARGUMENT ;
717+     }
718+ 
719+     return  UMF_RESULT_SUCCESS ;
720+ }
721+ 
722+ static  umf_result_t  os_open_ipc_handle (void  * provider , void  * providerIpcData ,
723+                                        void  * * ptr ) {
724+     if  (provider  ==  NULL  ||  providerIpcData  ==  NULL  ||  ptr  ==  NULL ) {
725+         return  UMF_RESULT_ERROR_INVALID_ARGUMENT ;
726+     }
727+ 
728+     os_memory_provider_t  * os_provider  =  (os_memory_provider_t  * )provider ;
729+     os_ipc_data_t  * os_ipc_data  =  (os_ipc_data_t  * )providerIpcData ;
730+ 
731+     int  fd  =  os_duplicate_fd (os_ipc_data -> pid , os_ipc_data -> fd );
732+     if  (fd  ==  -1 ) {
733+         LOG_PERR ("duplicating file descriptor failed" );
734+         return  UMF_RESULT_ERROR_UNKNOWN ;
735+     }
736+ 
737+     * ptr  =  os_mmap (NULL , os_ipc_data -> size , os_provider -> protection ,
738+                    os_provider -> flag , fd , os_ipc_data -> fd_offset );
739+     if  (* ptr  ==  NULL ) {
740+         os_store_last_native_error (UMF_OS_RESULT_ERROR_ALLOC_FAILED , errno );
741+         LOG_PERR ("memory mapping failed" );
742+         return  UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
743+     }
744+ 
745+     return  UMF_RESULT_SUCCESS ;
746+ }
747+ 
748+ static  umf_result_t  os_close_ipc_handle (void  * provider , void  * ptr ,
749+                                         size_t  size ) {
750+     if  (provider  ==  NULL  ||  ptr  ==  NULL ) {
751+         return  UMF_RESULT_ERROR_INVALID_ARGUMENT ;
752+     }
753+ 
754+     errno  =  0 ;
755+     int  ret  =  os_munmap (ptr , size );
756+     // ignore error when size == 0 
757+     if  (ret  &&  (size  >  0 )) {
758+         os_store_last_native_error (UMF_OS_RESULT_ERROR_FREE_FAILED , errno );
759+         LOG_PERR ("memory unmapping failed" );
760+ 
761+         return  UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
762+     }
763+ 
764+     return  UMF_RESULT_SUCCESS ;
765+ }
766+ 
669767static  umf_memory_provider_ops_t  UMF_OS_MEMORY_PROVIDER_OPS  =  {
670768    .version  =  UMF_VERSION_CURRENT ,
671769    .initialize  =  os_initialize ,
@@ -680,11 +778,11 @@ static umf_memory_provider_ops_t UMF_OS_MEMORY_PROVIDER_OPS = {
680778    .ext .purge_force  =  os_purge_force ,
681779    .ext .allocation_merge  =  os_allocation_merge ,
682780    .ext .allocation_split  =  os_allocation_split ,
683-     .ipc .get_ipc_handle_size  =  NULL ,
684-     .ipc .get_ipc_handle  =  NULL ,
685-     .ipc .put_ipc_handle  =  NULL ,
686-     .ipc .open_ipc_handle  =  NULL ,
687-     .ipc .close_ipc_handle  =  NULL };
781+     .ipc .get_ipc_handle_size  =  os_get_ipc_handle_size ,
782+     .ipc .get_ipc_handle  =  os_get_ipc_handle ,
783+     .ipc .put_ipc_handle  =  os_put_ipc_handle ,
784+     .ipc .open_ipc_handle  =  os_open_ipc_handle ,
785+     .ipc .close_ipc_handle  =  os_close_ipc_handle };
688786
689787umf_memory_provider_ops_t  * umfOsMemoryProviderOps (void ) {
690788    return  & UMF_OS_MEMORY_PROVIDER_OPS ;
0 commit comments