class_docstr: A version of concurrent.futures.Future / asyncio.Future that can be fulfilled from a separate process.
  Any process can access future status and set the result / exception and check for state.
  However, only the original process (i.e. the process that created the future) can await the result or exception.
  
  :param use_lock: if True, operations with MPFuture use a global lock to prevent concurrent writes to the same pipe;
    If set to False, writing to this future ignores global lock, slightly improving performance, but making user
    responsible for avoiding concurrent set_result / set_exception calls to futures with the same process of origin.
  
  :note: This is an internal primitive that is not guaranteed to work outside of hivemind applications.
   More specifically, there are two known limitations:
     - MPFuture works between processes created through inheritance (e.g. fork), *not* for independent processes
     - MPFuture is deterministic if only one process can call set_result/set_exception/set_running_or_notify_cancel
       and only the origin process can call result/exception/cancel.
class_docstr_tok: ["A","version","of","concurrent.futures.Future","\/","asyncio.Future","that","can","be","fulfilled","from","a","separate","process",".","Any","process","can","access","future","status","and","set","the","result","\/","exception","and","check","for","state",".","However",",","only","the","original","process","(","i.e",".","the","process","that","created","the","future",")","can","await","the","result","or","exception",".",":","param","use_lock",":","if","True",",","operations","with","MPFuture","use","a","global","lock","to","prevent","concurrent","writes","to","the","same","pipe",";","If","set","to","False",",","writing","to","this","future","ignores","global","lock",",","slightly","improving","performance",",","but","making","user","responsible","for","avoiding","concurrent","set_result","\/","set_exception","calls","to","futures","with","the","same","process","of","origin",".",":","note",":","This","is","an","internal","primitive","that","is","not","guaranteed","to","work","outside","of","hivemind","applications",".","More","specifically",",","there","are","two","known","limitations",":","-","MPFuture","works","between","processes","created","through","inheritance","(","e.g",".","fork",")",",","*","not","*","for","independent","processes","-","MPFuture","is","deterministic","if","only","one","process","can","call","set_result\/set_exception\/set_running_or_notify_cancel","and","only","the","origin","process","can","call","result\/exception\/cancel","."]
code: def _set_event_threadsafe(self):
      try:
          running_loop = asyncio.get_running_loop()
      except RuntimeError:
          running_loop = None
  
      async def _event_setter():
          self._aio_event.set()
  
      if self._loop.is_closed():
          return  # do nothing, the loop is already closed
      elif self._loop.is_running() and running_loop == self._loop:
          asyncio.create_task(_event_setter())
      elif self._loop.is_running() and running_loop != self._loop:
          asyncio.run_coroutine_threadsafe(_event_setter(), self._loop)
      else:
          self._loop.run_until_complete(_event_setter())
  
imports: from __future__ import annotations
  import asyncio
  import concurrent.futures._base
  import multiprocessing
  import os
  import threading
  import uuid
  from contextlib import nullcontext
  from enum import Enum, auto
  from multiprocessing.reduction import ForkingPickler
  from typing import Any, Callable, Dict, Generic, Optional, TypeVar
  from weakref import ref
  import torch
  from hivemind.utils.logging import get_logger
label_desc: Use image node_id 4 for calling the MPFuture obj's underlying member method code with example usage: obj._set_event_threadsafe() without return types