@@ -752,25 +752,51 @@ async def async_aux_get(self, mycpv, mylist, mytree=None, myrepo=None, loop=None
752752
753753        mydata , ebuild_hash  =  self ._pull_valid_cache (mycpv , myebuild , mylocation )
754754
755-         if  mydata  is  not   None :
756-             future  =  loop .create_future ()
757-             self ._aux_get_return (
758-                 future ,
759-                 mycpv ,
760-                 mylist ,
761-                 myebuild ,
762-                 ebuild_hash ,
763-                 mydata ,
764-                 mylocation ,
765-                 cache_me ,
766-                 None ,
767-             )
768-             return  future .result ()
755+         proc  =  None 
756+         if  mydata  is  None :
757+             if  myebuild  in  self ._broken_ebuilds :
758+                 raise  PortageKeyError (mycpv )
759+ 
760+             # Retry for an intermittent unexpected bash returncode which 
761+             # annoyingly occurs in CI runs with forkserver (bug 965132). 
762+             tries  =  3 
763+             while  tries  >  0 :
764+                 tries  -=  1 
765+                 proc  =  await  self ._run_metadata_phase (mycpv , mylocation , ebuild_hash )
766+ 
767+                 if  proc .returncode  !=  os .EX_OK :
768+                     if  proc .returncode  !=  1 :
769+                         writemsg (
770+                             _ (
771+                                 "!!! aux_get(): metadata phase for package '%(pkg)s' failed with unexpected returncode %(returncode)s\n " 
772+                             )
773+                             %  {"pkg" : mycpv , "returncode" : proc .returncode },
774+                             noiselevel = - 1 ,
775+                         )
776+                         # Only retry for an unexpected returncode. 
777+                         if  tries  >  0 :
778+                             continue 
779+                     self ._broken_ebuilds .add (myebuild )
780+                     raise  PortageKeyError (mycpv )
769781
770-         if   myebuild   in   self . _broken_ebuilds : 
771-             raise   PortageKeyError ( mycpv ) 
782+                  mydata   =   proc . metadata 
783+                  break 
772784
773-         proc  =  None 
785+         return  self ._aux_get_return (
786+             mycpv ,
787+             mylist ,
788+             myebuild ,
789+             ebuild_hash ,
790+             mydata ,
791+             mylocation ,
792+             cache_me ,
793+         )
794+ 
795+     async  def  _run_metadata_phase (
796+         self , mycpv , mylocation , ebuild_hash 
797+     ) ->  EbuildMetadataPhase :
798+ 
799+         loop  =  self ._event_loop 
774800        deallocate_config  =  None 
775801        async  with  contextlib .AsyncExitStack () as  stack :
776802            try :
@@ -800,21 +826,6 @@ async def async_aux_get(self, mycpv, mylist, mytree=None, myrepo=None, loop=None
800826                    deallocate_config = deallocate_config ,
801827                )
802828
803-                 future  =  loop .create_future ()
804-                 proc .addExitListener (
805-                     functools .partial (
806-                         self ._aux_get_return ,
807-                         future ,
808-                         mycpv ,
809-                         mylist ,
810-                         myebuild ,
811-                         ebuild_hash ,
812-                         mydata ,
813-                         mylocation ,
814-                         cache_me ,
815-                     )
816-                 )
817-                 future .add_done_callback (functools .partial (self ._aux_get_cancel , proc ))
818829                proc .start ()
819830
820831            finally :
@@ -824,46 +835,32 @@ async def async_aux_get(self, mycpv, mylist, mytree=None, myrepo=None, loop=None
824835                    if  proc  is  None  or  not  proc .isAlive ():
825836                        deallocate_config .done () or  deallocate_config .cancel ()
826837                    else :
827-                         await  deallocate_config 
838+                         try :
839+                             await  deallocate_config 
840+                         except  asyncio .CancelledError :
841+                             proc .cancel ()
842+                             raise 
828843
829844        # After deallocate_config is done, release self._doebuild_settings_lock 
830-         # by leaving the stack context, and wait for proc to finish and 
831-         # trigger a call to self._aux_get_return. 
832-         return  await  future 
833- 
834-     @staticmethod  
835-     def  _aux_get_cancel (proc , future ):
836-         if  future .cancelled () and  proc .returncode  is  None :
845+         # by leaving the stack context, and wait for proc to finish. 
846+         try :
847+             await  proc .async_wait ()
848+         except  asyncio .CancelledError :
837849            proc .cancel ()
850+             raise 
851+ 
852+         return  proc 
838853
839854    def  _aux_get_return (
840855        self ,
841-         future ,
842856        mycpv ,
843857        mylist ,
844858        myebuild ,
845859        ebuild_hash ,
846860        mydata ,
847861        mylocation ,
848862        cache_me ,
849-         proc ,
850863    ):
851-         if  future .cancelled ():
852-             return 
853-         if  proc  is  not   None :
854-             if  proc .returncode  !=  os .EX_OK :
855-                 if  proc .returncode  !=  1 :
856-                     writemsg (
857-                         _ (
858-                             "!!! aux_get(): metadata phase for package '%(pkg)s' failed with unexpected returncode %(returncode)s\n " 
859-                         )
860-                         %  {"pkg" : mycpv , "returncode" : proc .returncode },
861-                         noiselevel = - 1 ,
862-                     )
863-                 self ._broken_ebuilds .add (myebuild )
864-                 future .set_exception (PortageKeyError (mycpv ))
865-                 return 
866-             mydata  =  proc .metadata 
867864        mydata ["repository" ] =  self .repositories .get_name_for_location (mylocation )
868865        mydata ["_mtime_" ] =  ebuild_hash .mtime 
869866        eapi  =  mydata .get ("EAPI" )
@@ -882,7 +879,7 @@ def _aux_get_return(
882879                aux_cache [x ] =  mydata .get (x , "" )
883880            self ._aux_cache [mycpv ] =  aux_cache 
884881
885-         future . set_result ( returnme ) 
882+         return   returnme 
886883
887884    def  getFetchMap (self , mypkg , useflags = None , mytree = None ):
888885        """ 
0 commit comments