* Cleared up a misconception in the notification mechanism. We already had

methods that used an "event mask" field. There was no need to introduce
  a "flags" field for the same purpose.
* Renamed protected DefaultNotificationService methods (removed "_" prefix).
* Adjusted the code providing a notification service accordingly.
* Changed the event message several notification services generated by renaming
  the "opcode" field to "event".
* Implemented the TEAM_ADDED event and also added a TEAM_EXEC event.
* Added notifications for threads and images.
* Added visitor-like iteration functions for teams, threads, and images.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30126 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-04-11 21:45:25 +00:00
parent 78c00a4a53
commit efd536ff89
12 changed files with 242 additions and 113 deletions
+53
View File
@@ -30,6 +30,7 @@
#include <kimage.h>
#include <kscheduler.h>
#include <ksignal.h>
#include <Notifications.h>
#include <real_time_clock.h>
#include <smp.h>
#include <syscalls.h>
@@ -86,8 +87,32 @@ struct UndertakerEntry : DoublyLinkedListLinkImpl<UndertakerEntry> {
}
};
class ThreadNotificationService : public DefaultNotificationService {
public:
ThreadNotificationService()
: DefaultNotificationService("threads")
{
}
void Notify(uint32 eventCode, struct thread* thread)
{
char eventBuffer[128];
KMessage event;
event.SetTo(eventBuffer, sizeof(eventBuffer), THREAD_MONITOR);
event.AddInt32("event", eventCode);
event.AddInt32("thread", thread->id);
event.AddPointer("threadStruct", thread);
DefaultNotificationService::Notify(event, eventCode);
}
};
static DoublyLinkedList<UndertakerEntry> sUndertakerEntries;
static ConditionVariable sUndertakerCondition;
static ThreadNotificationService sNotificationService;
// The dead queue is used as a pool from which to retrieve and reuse previously
// allocated thread structs when creating a new thread. It should be gone once
@@ -504,6 +529,9 @@ create_thread(thread_creation_attributes& attributes, bool kernel)
thread->entry = attributes.entry;
status = thread->id;
// notify listeners
sNotificationService.Notify(THREAD_ADDED, thread);
if (kernel) {
// this sets up an initial kthread stack that runs the entry
@@ -1507,6 +1535,9 @@ thread_exit(void)
put_select_sync(sync);
}
// notify listeners
sNotificationService.Notify(THREAD_REMOVED, thread);
// shutdown the thread messaging
status = acquire_sem_etc(thread->msg.write_sem, 1, B_RELATIVE_TIMEOUT, 0);
@@ -1740,6 +1771,25 @@ thread_dequeue_id(struct thread_queue *q, thread_id id)
}
struct thread*
thread_iterate_through_threads(thread_iterator_callback callback, void* cookie)
{
struct hash_iterator iterator;
hash_open(sThreadHash, &iterator);
struct thread* thread;
while ((thread = (struct thread*)hash_next(sThreadHash, &iterator))
!= NULL) {
if (callback(thread, cookie))
break;
}
hash_close(sThreadHash, &iterator, false);
return thread;
}
thread_id
allocate_thread_id(void)
{
@@ -2099,6 +2149,9 @@ thread_init(kernel_args *args)
}
sUsedThreads = args->num_cpus;
// init the notification service
new(&sNotificationService) ThreadNotificationService();
// start the undertaker thread
new(&sUndertakerEntries) DoublyLinkedList<UndertakerEntry>();
sUndertakerCondition.Init(&sUndertakerEntries, "undertaker entries");