This commit contains a number of related mailbox issues: - Add extra parameters to mailbox_respond_receive to allow both the number of bytes/handles passed in, and the size of the byte/handle buffers to be passed in. - Don't delete mailbox messages on receipt if the caller is waiting on reply - Correctly pass status messages along with a mailbox::replyer object - Actually wake the calling thread in the mailbox::replyer dtor - Make sure to release locks _before_ calling thread::wake() on blocked threads, as that may cause them to be scheduled ahead of the current thread.
50 lines
922 B
C++
50 lines
922 B
C++
#include "objects/event.h"
|
|
#include "objects/thread.h"
|
|
|
|
namespace obj {
|
|
|
|
event::event() :
|
|
kobject {type::event},
|
|
m_signals {0}
|
|
{}
|
|
|
|
event::~event() {}
|
|
|
|
void
|
|
event::signal(uint64_t s)
|
|
{
|
|
uint64_t after = __atomic_or_fetch(&m_signals, s, __ATOMIC_SEQ_CST);
|
|
if (after) wake_observer();
|
|
}
|
|
|
|
uint64_t
|
|
event::wait()
|
|
{
|
|
// If events are pending, grab those and return immediately
|
|
uint64_t value = read();
|
|
if (value)
|
|
return value;
|
|
|
|
// Wait for event::signal() to wake us with a value
|
|
thread ¤t = thread::current();
|
|
m_queue.add_thread(¤t);
|
|
return current.block();
|
|
}
|
|
|
|
void
|
|
event::wake_observer()
|
|
{
|
|
util::scoped_lock lock {m_queue.get_lock()};
|
|
thread *t = m_queue.get_next_unlocked();
|
|
if (!t) return;
|
|
|
|
uint64_t value = read();
|
|
if (value) {
|
|
m_queue.pop_next_unlocked();
|
|
lock.release();
|
|
t->wake(value);
|
|
}
|
|
}
|
|
|
|
} // namespace obj
|