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
15static sem_id sRequestSem = -1;
16
17
18static int32
19invalidate_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
39static void
40exit_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
52static status_t
53std_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
78static 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
91module_info *modules[] = {
92	(module_info *)&sModuleInfo,
93	NULL
94};
95