
    & jD              	       $   % S r SSKrSSKJr  SSKJr  SSKJ	r
  SSKJrJrJrJrJrJrJr  SSKJrJr  SSKJrJr   " S	 S
\5      r " S S\5      r\" 5       S\" 5       SS/ 0 SS.r\\S'   S'S\\   SS4S jjrS(S\SS4S jjr S)S\!SS4S jjr"S'S\\   S\\\\\4   4   4S jjr#   S*S\S\\   S\\   SS4S jjr$S\S\4   S\S\\\\4      4   4S jr%S\\\\4      4S  jr&S\\\\4      4S! jr'S+S"\(S\!4S# jjr)S,S$\S%\SS4S& jjr*g)-z0.0.12    N)wraps)exit)_exit)AnyCallableDictListOptional	TypedDictUnion)Thread	Semaphore)Process	cpu_countc                   ^    \ rS rSr% Sr\\   \S'   \\	\
   \	\   4   \S'   \\S'   \\S'   Srg)	
PoolConfig$   zType definition for execution pool configuration.

This defines the structure of each pool in the POOLS dictionary,
containing the semaphore for limiting concurrent tasks, the engine
type (Thread or Process), pool name, and thread count.
poolenginenamethreads N)__name__
__module____qualname____firstlineno____doc__r
   r   __annotations__r   typer   r   strint__static_attributes__r       f/root/GenerationalWealth/GenerationalWealth/venv/lib/python3.13/site-packages/multitasking/__init__.pyr   r   $   s6     9
$v,W-..
ILr#   r   c                       \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\S'   \	\
\\4      \S'   \\\4   \S	'   \\S
'   Srg)Config1   zType definition for global multitasking configuration.

This structure holds all global state including CPU info, engine
preferences, task tracking, and pool management. It serves as the
central configuration store for the entire library.
	CPU_CORESENGINEMAX_THREADSDAEMONKILL_RECEIVEDTASKSPOOLS	POOL_NAMEr   N)r   r   r   r   r   r!   r   r    boolr	   r   r   r   r   r   r"   r   r#   r$   r&   r&   1   sL     NKLfgo&''Z  Nr#   r&   threadFMain)r(   r)   r*   r+   r,   r-   r.   r/   configr   returnc                 @    U b
  U [         S'   g[        5       [         S'   g)a  Configure the maximum number of concurrent threads/processes.

This function allows users to override the default CPU-based thread
count. Setting this affects new pools but not existing ones.

Args:
    threads: Maximum concurrent tasks. If None, uses CPU count.
             Must be positive integer or None.

Example:
    set_max_threads(4)  # Limit to 4 concurrent tasks
    set_max_threads()   # Reset to CPU count
Nr*   )r3   r   )r   s    r$   set_max_threadsr6   T   s"      '} !*}r#   kindc                 R    SU R                  5       ;   a
  S[        S'   gS[        S'   g)a  Configure the execution engine for new pools.

This determines whether new tasks run in threads or separate
processes. Threads share memory but processes are more isolated.
Only affects pools created after this call.

Args:
    kind: Engine type. Contains "process" for multiprocessing,
          anything else defaults to threading.

Note:
    Threading: Faster startup, shared memory, GIL limitations
    Processing: Slower startup, isolated memory, true parallelism
processr)   r1   N)lowerr3   )r7   s    r$   
set_enginer;   j   s(     DJJL $x $xr#   daemonc                 (    [        U 5      [        S'   g)uB  Configure whether new tasks spawn as daemon threads/processes.

Daemon tasks are terminated automatically when the interpreter
exits; non-daemon tasks block interpreter exit until they finish
(the long-standing default, which lets ``wait_for_tasks`` or a
plain script-end serve as an implicit join point).

Call this once, alongside :func:`set_engine`, when your code
contains long-lived ``@task`` workers (schedulers, pollers,
infinite cleanup loops) that must NOT block process exit — for
example in test suites, CLIs that shut down on SIGTERM, or any
application where tasks are fire-and-forget by design.

Args:
    daemon: True to spawn daemon tasks, False to preserve the
            historical non-daemon behavior (default).

Note:
    This setting affects only tasks spawned after the call.
    Existing tasks retain whatever daemon flag they were created
    with. Also affects Processes as well as Threads; for
    Processes the daemon flag additionally prevents them from
    spawning child processes of their own.

Example:
    import multitasking

    multitasking.set_engine("thread")
    multitasking.set_daemon(True)  # long-lived worker opt-in

    @multitasking.task
    def cleanup():
        while True:
            do_cleanup()
            time.sleep(60)

    cleanup()  # fires and forgets; exits cleanly with the process
r+   N)r0   r3   )r<   s    r$   
set_daemonr>      s    N F|F8r#   r   c                     U c	  [         S   n Sn[         S   [         S      S   [        :X  a  SnUU [         S   [         S      S   S.$ )an  Retrieve information about an execution pool.

Returns a dictionary with pool metadata including engine type,
name, and thread count. Useful for debugging and monitoring.

Args:
    name: Pool name to query. If None, uses current active pool.

Returns:
    Dictionary with keys: 'engine', 'name', 'threads'

Raises:
    KeyError: If the specified pool doesn't exist
r/   r1   r.   r   r9   r   )r   r   r   )r3   r   )r   r   s     r$   getPoolr@      sb      |k" Fgvk*+H5@ '?6+#67	B r#   r   c                 b   U [         S'    Ub  [        U5      O[         S   nUS:  a  SnUb  UO[         S   nU[         S'   U[         S'   US:  a  [	        U5      OSSUR                  5       ;   a  [        O[        U US.[         S	   [         S   '   g! [        [        4 a    [         S   n Nf = f)
ad  Create a new execution pool with specified configuration.

Pools manage concurrent task execution using semaphores. Each pool
has its own thread/process limit and engine type. Creating a pool
automatically makes it the active pool for new tasks.

Args:
    name: Unique identifier for this pool
    threads: Max concurrent tasks. None uses global MAX_THREADS.
             Values < 2 create unlimited pools (no semaphore).
    engine: "process" or "thread". None uses global ENGINE setting.

Note:
    Setting threads=0 or threads=1 creates an unlimited pool where
    all tasks run immediately without queuing.
r/   Nr*      r   r)   r9   )r   r   r   r   r.   )r3   r!   
ValueError	TypeErrorr   r:   r   r   )r   r   r   s      r$   
createPoolrE      s    , F;(#/CL& 	 { )Vvh/?F $F=F8
 '.k	'"t&&,,.8'f,F7OF;'(! 	" ('(s   B B.-B.callee.c           
         ^ ^ [         S   (       d
  [        5         S[        S[        S[        4U 4S jjm[        T 5      S[        S[        S[        [
        [        [        4      4UU 4S jj5       nU$ )uS  Decorator that converts a function into an asynchronous task.

This is the main decorator of the library. It wraps any function
to make it run asynchronously in the background using the current
pool's configuration (threads or processes).

The spawned Thread/Process inherits its ``daemon`` flag from the
global :data:`config` via :func:`set_daemon` — by default tasks
are non-daemon (Python waits for them on interpreter exit). For
fire-and-forget background workers, call
``multitasking.set_daemon(True)`` once before declaring the task.

Args:
    callee: The function to be made asynchronous

Returns:
    Decorated function that returns Thread/Process object or None

Example:
    @task
    def my_function(x, y):
        return x + y

    result = my_function(1, 2)  # Returns Thread/Process object
    wait_for_tasks()  # Wait for completion
r.   argskwargsr4   c                     > [         S   [         S      S   nUb  U   T" U 0 UD6sSSS5        $ T" U 0 UD6$ ! , (       d  f       g= f)a  Internal wrapper that handles semaphore-controlled execution.

This function is what actually runs in the background thread/process.
It acquires the pool's semaphore (if any) before executing the
original function, ensuring we don't exceed the concurrent limit.
r.   r/   r   Nr3   )rH   rI   r   rF   s      r$   _run_via_pooltask.<locals>._run_via_pool$  sT     gvk23F;t.v.  4*6**	 s	   7
Ac                  :  > [         S   [         S      S   S:X  a	  T" U 0 UD6  g[         S   (       dQ   [         S   [         S      S   nU" TU U[         S   S	9n[         S   R                  U5        UR                  5         U$ g! [         a    W" TU US
9n N?f = f)zThe actual decorated function that users call.

This decides whether to run synchronously (for 0-thread pools)
or asynchronously (for normal pools). It handles the creation
and startup of Thread/Process objects.
r.   r/   r   r   Nr,   r   r+   )targetrH   rI   r<   )rO   rH   rI   r-   )r3   	Exceptionappendstart)rH   rI   engine_classsinglerL   rF   s       r$   async_methodtask.<locals>.async_method4  s     '?6+./	:a?D#F# o&%gvk/BCHM &(!!(+	 7O""6* LLN M %  %(!s   &B BB)r3   rE   r   r   r
   r   r   r   )rF   rU   rL   s   ` @r$   taskrW     sr    < '?+S +C +C +  6]44!4	%(	)4 4l r#   c                      [         S   $ )ay  Retrieve all tasks ever created by this library.

This includes both currently running tasks and completed ones.
Useful for debugging and monitoring task history.

Returns:
    List of all Thread/Process objects created by @task decorator

Note:
    Completed tasks remain in this list until program termination.
    Use get_active_tasks() to see only currently running tasks.
r-   rK   r   r#   r$   get_list_of_tasksrY   n  s     '?r#   c                  l    [         S    V s/ s H  o R                  5       (       d  M  U PM     sn $ s  sn f )ak  Retrieve only the currently running tasks.

Filters the complete task list to show only tasks that are still
executing. This is more useful than get_list_of_tasks() for
monitoring current system load.

Returns:
    List of Thread/Process objects that are still running

Example:
    active = get_active_tasks()
    print(f"Currently running {len(active)} tasks")
r-   )r3   is_alive)rW   s    r$   get_active_tasksr\   ~  s&     $G_@_TD_@@@s   11sleepc                    S[         S'   [         S   [         S      S   S:X  a  g  [         S    Vs/ s H!  nUc  M  UR                  5       (       d  M  UPM#     nnU H  nUR                  S5        M     [        [         S    Vs/ s H!  nUc  M  UR                  5       (       d  M  UPM#     sn5      nUS:X  a  OU S:  a  [        R
                  " U 5        M  S	[         S'   gs  snf s  snf ! [         a     N f = f)
a'  Block until all background tasks complete execution.

This is the primary synchronization mechanism. It prevents new
tasks from being created and waits for existing ones to finish.
Essential for ensuring all work is done before program exit.

Args:
    sleep: Seconds to sleep between checks. 0 means busy-wait.
           Higher values reduce CPU usage but increase latency.

Returns:
    Always returns True when all tasks are complete

Note:
    Sets KILL_RECEIVED=True during execution to prevent new tasks,
    then resets it to False when done.
Tr,   r.   r/   r   r   r-      F)r3   r[   joinlen_timer]   rP   )r]   rW   running_tasksstill_runnings       r$   wait_for_tasksre     s   & #F? gvk*+I6!; "(!0 (,    &		! &  !'!!0 (, ! M ! qyE"1 > $F?=!  sK   C. C$C$C$,C. C)C)(C).C. <C. $
C. .
C;:C;selfclsc                 v    S[         S'    [        S5        S[         S'   g! [         a    [        S5         N!f = f)a  Emergency shutdown function that terminates the entire program.

This is a last-resort function that immediately exits the program,
potentially leaving tasks in an inconsistent state. It tries
sys.exit() first, then os._exit() as a final measure.

Args:
    self: Unused parameter kept for backward compatibility
    cls: Unused parameter kept for backward compatibility

Warning:
    This function does NOT wait for tasks to complete cleanly.
    Use wait_for_tasks() for graceful shutdown instead.

Note:
    The function attempts sys.exit(0) first (which allows cleanup
    handlers to run), falling back to os._exit(0) which terminates
    immediately without any cleanup.
Tr,   r   FN)r3   sysexit
SystemExitosexit)rf   rg   s     r$   killallrl     s>    * #F?
 $F?  q	s     88)N) )F)mainNN)r   )NN)+__version__timerb   	functoolsr   sysr   ri   osr   rk   typingr   r   r   r	   r
   r   r   	threadingr   r   multiprocessingr   r   r   r&   r3   r   r!   r6   r    r;   r0   r>   r@   rE   rW   rY   r\   floatre   rl   r   r#   r$   <module>rx      s  , h     H H H ( .
 
Y ( ;
   ,Xc] ,d ,,$S $$ $.'$t '$ '$T(3- 4U38_0D+E B ! 5
5c]5 SM5 
	5phS#Xhc8E&'/2334hV4fgo 67  A$uVW_56 A";% ; ;|$# $3 $$ $r#   