|
| 1 | +# The Volatile Keyword in NetWebView2Lib |
| 2 | + |
| 3 | +In **NetWebView2Lib**, callback functions such as `JS_Events_OnMessageReceived` and `OnBasicAuthenticationRequested` **must** be declared using the `Volatile` qualifier. This is a technical requirement for reliable interaction between AutoIt and the WebView2 runtime. |
| 4 | + |
| 5 | +## What `Volatile` Does |
| 6 | +The `Volatile` keyword enables **re-entrant execution**. |
| 7 | +* **With Volatile:** While a function is running, AutoIt continues to process its internal message loop, including GUI and COM events. |
| 8 | +* **Without Volatile:** AutoIt pauses message processing until the function returns. |
| 9 | + |
| 10 | +## Why It Is Required |
| 11 | + |
| 12 | +### 1. Continuous Message Processing |
| 13 | +WebView2 communicates with AutoIt through COM events. If AutoIt stops processing messages while handling a callback, incoming events may be delayed or blocked. Declaring the function as `Volatile` ensures that message handling continues during execution, preventing the interface from becoming unresponsive. |
| 14 | + |
| 15 | +### 2. Synchronous COM Callbacks |
| 16 | +WebView2 event handlers are invoked through **synchronous COM calls**. This means the WebView2 process waits for AutoIt to finish executing the callback before continuing. If AutoIt is busy (e.g., during GUI interaction like moving the window), the WebView2 process may stall. Using `Volatile` allows the callback to execute without interrupting message handling. |
| 17 | + |
| 18 | +### 3. Deadlock Prevention |
| 19 | +Because AutoIt and WebView2 run in separate processes, improper message handling can lead to deadlocks. |
| 20 | +> **Deadlock Scenario:** |
| 21 | +> 1. WebView2 triggers a callback and waits for AutoIt to return. |
| 22 | +> 2. AutoIt is blocked (e.g. by a system menu or moving the GUI) and is not processing messages. |
| 23 | +> 3. Neither process can continue, resulting in a frozen application. |
| 24 | +
|
| 25 | +Declaring callbacks as `Volatile` prevents this by allowing AutoIt to remain responsive. |
| 26 | + |
| 27 | +## Rule of Thumb |
| 28 | +**All functions used as WebView2 event handlers MUST be declared Volatile.** |
| 29 | + |
| 30 | +## Example |
| 31 | +```autoit |
| 32 | +; WebView2 callback must be declared as Volatile |
| 33 | +Volatile Func JS_Events_OnMessageReceived($oWebV2M, $hGUI, $sMessage) |
| 34 | + ; Handle message from WebView2 |
| 35 | + ConsoleWrite("Message received: " & $sMessage & @CRLF) |
| 36 | +EndFunc |
| 37 | +``` |
| 38 | + |
| 39 | +## Object Cleanup |
| 40 | + |
| 41 | +In AutoIt, when working with COM objects (like the WebView2 Manager or Bridge), it is highly recommended to explicitly release the object references when they are no longer needed. |
| 42 | + |
| 43 | +### Why zero out objects? |
| 44 | + |
| 45 | +1. **Reference Counting:** COM objects use reference counting. The object stays in memory as long as there is at least one active reference to it. Setting `$oObject = 0` decrements this count. |
| 46 | + |
| 47 | +2. **Preventing Memory Leaks:** If a script runs for a long time and repeatedly creates objects without releasing them, it will consume increasing amounts of RAM. |
| 48 | + |
| 49 | +3. **Proper Shutdown:** WebView2 is an external process. Explicitly cleaning up ensures that the underlying `WebView2Loader` and Chromium processes terminate correctly when your GUI closes. |
| 50 | + |
| 51 | + |
| 52 | +### Implementation Example |
| 53 | + |
| 54 | +Always pair your initialization with a cleanup block, typically before the script exits: |
| 55 | + |
| 56 | + |
| 57 | +```AutoIt |
| 58 | +; ... inside your Exit logic ... |
| 59 | +
|
| 60 | +; 1. Call the UDF's cleanup function to release internal resources |
| 61 | +_NetWebView2_CleanUp($oWebV2M, $oBridge) |
| 62 | +
|
| 63 | +; 2. Explicitly nullify the object variables |
| 64 | +$oBridge = 0 |
| 65 | +$oWebV2M = 0 |
| 66 | +
|
| 67 | +Exit |
| 68 | +``` |
| 69 | + |
| 70 | +> **Tip:** In `Volatile` functions, if you receive an object as an argument (like `$oArgs`), it is a good habit to set `$oArgs = 0` at the end of the function to ensure the COM reference is released immediately after the event is handled. |
0 commit comments