Repository navigation
Async and Multi Interface
The Multi interface drives concurrent transfers through a shared pool. Multiple easy handles are added to a multi handle, and Async() polls the pool until all transfers complete.
MultiInit creates a new multi_handle. One is automatically established during LibQurl(), but you can create additional pools to group downloads as desired:
first_pool := curl.MultiInit()
second_pool := curl.MultiInit()ReadyAsync adds easy_handles to a multi_handle pool. Accepts a single handle or an array:
; Single handle
curl.ReadyAsync(easy_handle)
; Batch
easyHandles := [easy1, easy2, easy3]
curl.ReadyAsync(easyHandles, multi_handle)The multi_handle parameter is optional and defaults to the oldest created pool.
Async performs one pass of the transfer cycle and returns a still_running boolean (1 or 0). Poll in a loop until all transfers in the pool are complete:
curl.ReadyAsync([easy1, easy2, easy3])
Loop {
still_running := curl.Async()
} Until !still_runningTiming between iterations is caller-controlled. libcurl handles the network layer and keep-alive internally. Any reasonable non-blocking yield works.
You can maintain multiple multi pools and poll them in the same loop:
first_pool := curl.MultiInit()
second_pool := curl.MultiInit()
curl.ReadyAsync([easy1, easy2], first_pool)
curl.ReadyAsync([easy3, easy4], second_pool)
Loop {
check := 0
check += curl.Async(first_pool)
check += curl.Async(second_pool)
} Until !checkSwapMultiPools transfers easy handles from one pool to another:
curl.SwapMultiPools([easyA, easyB], first_pool, second_pool)The handles are removed from the source pool and added to the destination pool.
Calling Sync on a handle that is currently in a multi_handle pool automatically removes it from the pool first. This prevents a handle from being driven by both interfaces simultaneously:
; This handle was added to the pool via ReadyAsync
; Sync removes it from the pool and performs the transfer synchronously
curl.Sync(easy_handle)However, there are no checks to see if the easy_handle is being actively used by the multi_handle, so consider this a safety net rather than reliable full protection.
Once a transfer completes, the easy_handle can be reconfigured and added back to a multi_handle pool:
curl.SetOpt("URL", "https://example.com/next-download", easy_handle)
curl.WriteToFile("C:\downloads\next-file.bin", easy_handle)
curl.ReadyAsync(easy_handle, first_pool)
Loop {
still_running := curl.Async(first_pool)
} Until !still_running; Counts: current, running, pending, done, added
info := curl.GetMultiInfo(multi_handle)
MsgBox curl.PrintObj(info)
; Completed transfer details from the multi_handle pool's message queue
completed := curl.MultiInfoRead(multi_handle)
MsgBox curl.PrintObj(completed)
; List all easy handles currently in the pool
handles := curl.MultiGetHandles(multi_handle)
MsgBox handles.Length " handles in pool"
## Cleanup
`MultiCleanup` releases the multi_handle and all easy_handles associated with it. Any handles you want to keep should be removed via `RemoveEasyFromMulti` first:
```ahk
; Keep easy1, release the rest and the pool
curl.RemoveEasyFromMulti(easy1, multi_handle)
curl.MultiCleanup(multi_handle)- Raw Send and Receive — protocol-level data transfer
- Multi Handle Reference — full method list
Foundations
Operations
- Download Modes
- Setting and Listing Options
- Setting and Inspecting Headers
- POST and Upload
- Multiple Easy Handles
- Async and Multi Interface
- URL Construction
- Share Interface
- MIME and Multipart
- Raw Send and Receive
- Pause and Resume
- WebSocket
- SSL Sessions
- Debug and Diagnostics
API Reference
- Easy Handle Reference
- Multi Handle Reference
- Share Handle Reference
- MIME Handle Reference
- URL Handle Reference
- Utility Methods Reference
- WebSocket Reference
Code Snippets