1 /* 2 * Copyright 2008, Michael Lotz, mmlr@mlotz.ch 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <debug.h> 8 9 #include <signal.h> 10 11 #include <kscheduler.h> 12 #include <smp.h> 13 14 15 static sem_id sRequestSem = -1; 16 17 18 static int32 19 invalidate_loop(void *data) 20 { 21 while (true) { 22 if (acquire_sem(sRequestSem) != B_OK) 23 break; 24 25 uint32 message[3]; 26 message[0] = sizeof(message); // size 27 message[1] = 'KDLE'; // message code 28 message[2] = 0; // flags 29 30 // where "d:0:baron' stands for desktop x of user y which both 31 // currently are hardcoded and where '_PTL' is the port link code 32 write_port(find_port("d:0:baron"), '_PTL', &message, sizeof(message)); 33 } 34 35 return 0; 36 } 37 38 39 static void 40 exit_debugger() 41 { 42 // If someone holds the scheduler lock at this point, release_sem_etc() 43 // will block forever. So avoid that. 44 if (!try_acquire_spinlock(&gSchedulerLock)) 45 return; 46 release_spinlock(&gSchedulerLock); 47 48 release_sem_etc(sRequestSem, 1, B_DO_NOT_RESCHEDULE); 49 } 50 51 52 static status_t 53 std_ops(int32 op, ...) 54 { 55 if (op == B_MODULE_INIT) { 56 sRequestSem = create_sem(0, "invalidate_loop_request"); 57 if (sRequestSem < B_OK) 58 return sRequestSem; 59 60 thread_id thread = spawn_kernel_thread(&invalidate_loop, 61 "invalidate_loop", B_NORMAL_PRIORITY, NULL); 62 if (thread < B_OK) 63 return thread; 64 65 resume_thread(thread); 66 return B_OK; 67 } else if (op == B_MODULE_UNINIT) { 68 // deleting the sem will also cause the thread to exit 69 delete_sem(sRequestSem); 70 sRequestSem = -1; 71 return B_OK; 72 } 73 74 return B_BAD_VALUE; 75 } 76 77 78 static struct debugger_module_info sModuleInfo = { 79 { 80 "debugger/invalidate_on_exit/v1", 81 B_KEEP_LOADED, 82 &std_ops 83 }, 84 85 NULL, 86 exit_debugger, 87 NULL, 88 NULL 89 }; 90 91 module_info *modules[] = { 92 (module_info *)&sModuleInfo, 93 NULL 94 }; 95