Tech Tip: Synchronize Async Socket Initialization in Shared Classes
PRODUCT: 4D | VERSION: 20 R | PLATFORM: Mac & Win
Published On: November 6, 2025
When creating UDPSocket instances via CALL WORKER in a shared class constructor, the main thread continues immediately. Using the sockets before the worker completes can lead to undefined behavior like blocked callbacks (e.g., onData) or socket creation failure.
Use a Shared object and Signal to block safely until socket creation finishes
Benefits
Code Example
Use a Shared object and Signal to block safely until socket creation finishes
Benefits
- Sockets are fully initialized before any use.
- No race conditions in shared class workflows.
Code Example
| //Class : MyUDP property listener : 4D.UDPSocket property sender : 4D.UDPSocket property Port : Integer shared Class constructor($options : Object) This.Port:=(OB Is defined($options; "port")) ? OB Get($options; "port") : 32154 var $socketHolder : Object := New shared object() Use ($socketHolder) $socketHolder.listener := Null $socketHolder.sender := Null $socketHolder.endOfInitialization := New signal End use CALL WORKER("SocketWorker"; Formula($1._initSockets($2)); This; $socketHolder) $socketHolder.endOfInitialization.wait() // Wait for sockets to be ready This.listener := $socketHolder.listener This.sender := $socketHolder.sender //Class function Function _initSockets($socketHolder : Object) Use ($socketHolder) $socketHolder.listener:=4D.UDPSocket.new(This.Port; This) $socketHolder.sender:=4D.UDPSocket.new(0; This) End use $socketHolder.endOfInitialization.trigger() |