Dispatch

RSS for tag

Execute code concurrently on multicore hardware by submitting work to dispatch queues managed by the system using Dispatch.

Posts under Dispatch tag

26 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Question regards thread safety for Dispatch queue and Network Framework completion callbacks
Hi there, I have some thread related questions regards to network framework completion callbacks. In short, how should I process cross thread data in the completion callbacks? Here are more details. I have a background serial dispatch queue (call it dispatch queue A) to sequentially process the nw_connection and any network io events. Meanwhile, user inputs are handled by serial dispatch queue ( dispatch queue B). How should I handle the cross thread user data in this case? (I write some simplified sample code below) struct { int client_status; char* message_to_sent; }user_data; nw_connection_t nw_connection; dispatch_queue_t dispatch_queue_A static void send_message(){ dispatch_data_t data = dispatch_data_create(message, len(message), dispath_event_loop->dispatch_queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT); nw_connection_send( nw_connection, data, NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT, false, ^(nw_error_t error) { user_data.client_status = SENT; mem_release(user_data.message_to_sent); }); }); } static void setup_connection(){ dispatch_queue_A= dispatch_queue_create("unique_id_a", DISPATCH_QUEUE_SERIAL); nw_connection = nw_connection_create(endpoint, params); nw_connection_set_state_changed_handler(){ if (state == nw_connection_state_ready) { user_data.client_status = CONNECTED } // ... other operations ... } nw_connection_start(nw_connection); nw_retain(nw_connection); } static void user_main(){ setup_connection() user_data.client_status = INIT; dispatch_queue_t dispatch_queue_B = dispatch_queue_create("unique_id_b", DISPATCH_QUEUE_SERIAL); // write socket dispatch_async(dispatch_queue_B, ^(){ if (user_data.client_status != CONNECTED ) return; user_data.message_to_sent = malloc(XX,XXX) // I would like to have all io events processed on dispatch queue A so that the io events would not interacted with the user events dispatch_async_f(dispatch_queue_A, send_message); // Disconnect block dispatch_async(dispatch_queue_B, ^(){ dispatch_async_f(dispatch_queue_A, ^(){ nw_connection_cancel(nw_connection) }); user_data.client_status = DISCONNECTING; }); // clean up connection and so on... } To be more specific, my questions would be: As I was using serial dispatch queue, I didn't protect the user_data here. However, which thread would the send_completion_handler get called? Would it be a data race condition where the Disconnect block and send_completion_handler both access user_data? If I protect the user_data with lock, it might block the thread. How does the dispatch queue make sure it would NOT put a related execution block onto the "blocked thread"?
4
0
741
Sep ’24
serial dispatch_queue_t crashed
background info: I dispatch async task to main queue in an es_handler_block_t(client subscribe open, create, exit, close events and mute all processes except DesktopServicesHelper). crash happened kinda randomly. most likely to happen when I copy a folder(contains a lot of files) in a volume to another volume. here's the crashed part of the diagnostic report . Thread 9 Crashed:: Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x18c6e2a60 __pthread_kill + 8 1 libsystem_pthread.dylib 0x18c71ac20 pthread_kill + 288 2 libsystem_c.dylib 0x18c627a20 abort + 180 3 libc++abi.dylib 0x18c6d1d30 abort_message + 132 4 libc++abi.dylib 0x18c6c1fe8 demangling_terminate_handler() + 348 5 libobjc.A.dylib 0x18c3601d0 _objc_terminate() + 144 6 libc++abi.dylib 0x18c6d10f4 std::__terminate(void (*)()) + 16 7 libc++abi.dylib 0x18c6d1098 std::terminate() + 108 8 libdispatch.dylib 0x18c56a3fc _dispatch_client_callout + 40 9 libdispatch.dylib 0x18c571a14 _dispatch_lane_serial_drain + 748 10 libdispatch.dylib 0x18c572578 _dispatch_lane_invoke + 432 11 libdispatch.dylib 0x18c57bea8 _dispatch_root_queue_drain + 392 12 libdispatch.dylib 0x18c57c6b8 _dispatch_worker_thread2 + 156 13 libsystem_pthread.dylib 0x18c716fd0 _pthread_wqthread + 228 14 libsystem_pthread.dylib 0x18c715d28 start_wqthread + 8 Thread 9 crashed with ARM Thread State (64-bit): x0: 0x0000000000000000 x1: 0x0000000000000000 x2: 0x0000000000000000 x3: 0x0000000000000000 x4: 0x000000018c6d62cb x5: 0x000000016c1eed20 x6: 0x000000000000006e x7: 0x0000000000000000 x8: 0x851ef9fdee51098d x9: 0x851ef9fc824ff98d x10: 0x0000000000000200 x11: 0x000000000000000b x12: 0x0000000000000000 x13: 0x00000000001ff800 x14: 0x00000000000007fb x15: 0x00000000a5a0204e x16: 0x0000000000000148 x17: 0x00000001fe792c30 x18: 0x0000000000000000 x19: 0x0000000000000006 x20: 0x000000016c1ef000 x21: 0x0000000000004003 x22: 0x000000016c1ef0e0 x23: 0x000000016c1ef0e0 x24: 0x00000001f442b6a8 x25: 0x0000000000000000 x26: 0x0000000000000000 x27: 0x0000600003664800 x28: 0x0000000000000000 fp: 0x000000016c1eec90 lr: 0x000000018c71ac20 sp: 0x000000016c1eec70 pc: 0x000000018c6e2a60 cpsr: 0x40001000 far: 0x0000000000000000 esr: 0x56000080 Address size fault
1
0
814
Jul ’24
DispatchIO crashes, tips on debugging?
BUG IN CLIENT OF LIBDISPATCH: Unexpected EV_VANISHED (do not destroy random mach ports or file descriptors) Which, ok, clear: somehow a file descriptor is being closed before DispatchIO.close() is called, yes? Only I can't figure out where it is being closed. I am currently using change_fdguard_np() to prevent closes anywhere else, and every single place where I call Darwin.close() is preceded by another call to change_fdguard_npand thenDispatchIO.close()`. eg self.unguardSocket() self.readDispatcher?.close() Darwin.close(self.socket) self.socket = -1 self.completion(self)
11
0
866
Jul ’24
Concurrency Resources
Swift Concurrency Resources: DevForums tags: Concurrency The Swift Programming Language > Concurrency documentation Migrating to Swift 6 documentation WWDC 2022 Session 110351 Eliminate data races using Swift Concurrency — This ‘sailing on the sea of concurrency’ talk is a great introduction to the fundamentals. WWDC 2021 Session 10134 Explore structured concurrency in Swift — The table that starts rolling out at around 25:45 is really helpful. Swift Async Algorithms package Swift Concurrency Proposal Index DevForum post Why is flow control important? DevForums post Matt Massicotte’s blog Dispatch Resources: DevForums tags: Dispatch Dispatch documentation — Note that the Swift API and C API, while generally aligned, are different in many details. Make sure you select the right language at the top of the page. Dispatch man pages — While the standard Dispatch documentation is good, you can still find some great tidbits in the man pages. See Reading UNIX Manual Pages. Start by reading dispatch in section 3. WWDC 2015 Session 718 Building Responsive and Efficient Apps with GCD [1] WWDC 2017 Session 706 Modernizing Grand Central Dispatch Usage [1] Avoid Dispatch Global Concurrent Queues DevForums post Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" [1] These videos may or may not be available from Apple. If not, the URL should help you locate other sources of this info.
0
0
1.7k
Dec ’24
dispatch_async_f does not return immediatly
Hi, I work on a game for iOS and the framerate decreases progressively when the debugger is attached. Running it for 2mins, it went from 30 to 1 FPS while rendering a simple static scene. I narrowed it down to a call to dispatch_async_f which takes longer to execute over time. clock_t t1 = clock(); dispatch_async_f(queue, context, function); clock_t t2 = clock(); double duration = (double)(t2 -t1)/(double)CLOCKS_PER_SEC; Dodumentation says dispatch_async_f is supposed to return immediatly. So what could explain duration to increases in debug? Am i measuring this incorrectly? The game is written in mixed C++ and ObjC. It uses Metal as graphic API and GCD for dispatching jobs. I have Xcode 13.4.1 and test on an iPhone 13 Pro with iOS 15.7. Thanks.
10
0
2.6k
Sep ’24