1*0f4c859eSApple OSS Distributions #include <mach/port.h> 2*0f4c859eSApple OSS Distributions #include <mach/mach.h> 3*0f4c859eSApple OSS Distributions #include <sys/event.h> 4*0f4c859eSApple OSS Distributions #include <dispatch/dispatch.h> 5*0f4c859eSApple OSS Distributions #include <pthread/workqueue_private.h> 6*0f4c859eSApple OSS Distributions #include <darwintest.h> 7*0f4c859eSApple OSS Distributions 8*0f4c859eSApple OSS Distributions T_GLOBAL_META( 9*0f4c859eSApple OSS Distributions T_META_NAMESPACE("xnu.workq"), 10*0f4c859eSApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"), 11*0f4c859eSApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("workq"), 12*0f4c859eSApple OSS Distributions T_META_RUN_CONCURRENTLY(true)); 13*0f4c859eSApple OSS Distributions 14*0f4c859eSApple OSS Distributions T_DECL(thread_request_83476290, 15*0f4c859eSApple OSS Distributions "test that mach_msg_trap causes a thread request") 16*0f4c859eSApple OSS Distributions { 17*0f4c859eSApple OSS Distributions mach_port_t mp, rp; 18*0f4c859eSApple OSS Distributions kern_return_t kr; 19*0f4c859eSApple OSS Distributions dispatch_source_t ds; 20*0f4c859eSApple OSS Distributions dispatch_queue_t dq; 21*0f4c859eSApple OSS Distributions int kq; 22*0f4c859eSApple OSS Distributions 23*0f4c859eSApple OSS Distributions mach_port_options_t opts = { 24*0f4c859eSApple OSS Distributions .flags = MPO_INSERT_SEND_RIGHT, 25*0f4c859eSApple OSS Distributions }; 26*0f4c859eSApple OSS Distributions 27*0f4c859eSApple OSS Distributions kr = mach_port_construct(mach_task_self(), &opts, 0, &mp); 28*0f4c859eSApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "create receive right %x", mp); 29*0f4c859eSApple OSS Distributions 30*0f4c859eSApple OSS Distributions kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &rp); 31*0f4c859eSApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "create reply port right %x", rp); 32*0f4c859eSApple OSS Distributions 33*0f4c859eSApple OSS Distributions dq = dispatch_queue_create_with_target("tr.q", DISPATCH_QUEUE_SERIAL, NULL); 34*0f4c859eSApple OSS Distributions ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, mp, 0, dq); 35*0f4c859eSApple OSS Distributions dispatch_source_set_event_handler(ds, ^{ 36*0f4c859eSApple OSS Distributions T_PASS("received the event"); 37*0f4c859eSApple OSS Distributions T_END; 38*0f4c859eSApple OSS Distributions }); 39*0f4c859eSApple OSS Distributions dispatch_activate(ds); 40*0f4c859eSApple OSS Distributions 41*0f4c859eSApple OSS Distributions T_LOG("wait 1ms for the existing dispatch thread to park again"); 42*0f4c859eSApple OSS Distributions usleep(1000); 43*0f4c859eSApple OSS Distributions 44*0f4c859eSApple OSS Distributions kq = kqueue(); 45*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(kq, "kqueue()"); 46*0f4c859eSApple OSS Distributions 47*0f4c859eSApple OSS Distributions /* 48*0f4c859eSApple OSS Distributions * Now use the threads that were on the pool to make sure the process 49*0f4c859eSApple OSS Distributions * is starved 50*0f4c859eSApple OSS Distributions */ 51*0f4c859eSApple OSS Distributions dispatch_async(dispatch_get_global_queue(0, 0), ^{ 52*0f4c859eSApple OSS Distributions usleep(1000); 53*0f4c859eSApple OSS Distributions struct kevent_qos_s ke = { 54*0f4c859eSApple OSS Distributions .ident = 1, 55*0f4c859eSApple OSS Distributions .filter = EVFILT_USER, 56*0f4c859eSApple OSS Distributions .fflags = NOTE_TRIGGER, 57*0f4c859eSApple OSS Distributions }; 58*0f4c859eSApple OSS Distributions int rc = kevent_qos(kq, &ke, 1, NULL, 0, NULL, NULL, 0); 59*0f4c859eSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(rc, "NOTE_TRIGGER"); 60*0f4c859eSApple OSS Distributions pause(); 61*0f4c859eSApple OSS Distributions }); 62*0f4c859eSApple OSS Distributions 63*0f4c859eSApple OSS Distributions struct kevent_qos_s ke = { 64*0f4c859eSApple OSS Distributions .ident = 1, 65*0f4c859eSApple OSS Distributions .filter = EVFILT_USER, 66*0f4c859eSApple OSS Distributions .flags = EV_ADD | EV_CLEAR, 67*0f4c859eSApple OSS Distributions }; 68*0f4c859eSApple OSS Distributions 69*0f4c859eSApple OSS Distributions T_LOG("block in kevent, call mach_msg with 5s timeout"); 70*0f4c859eSApple OSS Distributions (void)kevent_qos(kq, &ke, 1, &ke, 1, NULL, NULL, 0); 71*0f4c859eSApple OSS Distributions 72*0f4c859eSApple OSS Distributions mach_msg_header_t hdr = { 73*0f4c859eSApple OSS Distributions .msgh_remote_port = mp, 74*0f4c859eSApple OSS Distributions .msgh_local_port = rp, 75*0f4c859eSApple OSS Distributions .msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND, 76*0f4c859eSApple OSS Distributions MACH_MSG_TYPE_MAKE_SEND_ONCE, 0, 0), 77*0f4c859eSApple OSS Distributions .msgh_id = 1, 78*0f4c859eSApple OSS Distributions .msgh_size = sizeof(hdr), 79*0f4c859eSApple OSS Distributions }; 80*0f4c859eSApple OSS Distributions 81*0f4c859eSApple OSS Distributions kr = mach_msg(&hdr, MACH_SEND_MSG | MACH_RCV_MSG | MACH_RCV_TIMEOUT, 82*0f4c859eSApple OSS Distributions sizeof(hdr), sizeof(hdr), rp, 5000, 0); 83*0f4c859eSApple OSS Distributions T_FAIL("mach_msg returned: %#x", kr); 84*0f4c859eSApple OSS Distributions } 85