From b4ec7b8ee52c34fb6edce3e9cf2806f5c04a25c9 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 15 Sep 2008 12:59:49 +0000 Subject: [PATCH] Added (kernel private) B_PEEK_PORT_MESSAGE flag for read_port_etc(). When specified, the message is read but not removed from the port. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27527 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/port.h | 11 ++++++++++- src/system/kernel/port.cpp | 25 ++++++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/headers/private/kernel/port.h b/headers/private/kernel/port.h index 6e47e93bd4..bcc07f8f2c 100644 --- a/headers/private/kernel/port.h +++ b/headers/private/kernel/port.h @@ -15,6 +15,14 @@ struct select_info; #define PORT_FLAG_USE_USER_MEMCPY 0x80000000 +// port flags +enum { + // read_port_etc() flags + B_PEEK_PORT_MESSAGE = 0x100 // read the message, but don't remove it; + // kernel-only; memory must be locked +}; + + #ifdef __cplusplus extern "C" { #endif @@ -29,7 +37,8 @@ status_t deselect_port(int32 object, struct select_info *info, bool kernel); // currently private API status_t writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs, - size_t vecCount, size_t bufferSize, uint32 flags, bigtime_t timeout); + size_t vecCount, size_t bufferSize, uint32 flags, + bigtime_t timeout); // temp: test void port_test(void); diff --git a/src/system/kernel/port.cpp b/src/system/kernel/port.cpp index 0a0b6154e2..18971bdda0 100644 --- a/src/system/kernel/port.cpp +++ b/src/system/kernel/port.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -369,7 +370,7 @@ port_init(kernel_args *args) // #pragma mark - public kernel API -port_id +port_id create_port(int32 queueLength, const char *name) { cpu_status state; @@ -575,7 +576,7 @@ delete_port(port_id id) RELEASE_PORT_LOCK(sPorts[slot]); - // update the first free slot hint in the array + // update the first free slot hint in the array GRAB_PORT_LIST_LOCK(); if (slot < sFirstFreeSlot) sFirstFreeSlot = slot; @@ -959,7 +960,8 @@ read_port_etc(port_id id, int32 *_msgCode, void *msgBuffer, size_t bufferSize, cpu_status state; sem_id cachedSem; status_t status; - bool userCopy = (flags & PORT_FLAG_USE_USER_MEMCPY) > 0; + bool userCopy = (flags & PORT_FLAG_USE_USER_MEMCPY) != 0; + bool peekOnly = !userCopy && (flags & B_PEEK_PORT_MESSAGE) != 0; port_msg *msg; size_t size; int slot; @@ -1024,6 +1026,19 @@ read_port_etc(port_id id, int32 *_msgCode, void *msgBuffer, size_t bufferSize, return B_BAD_PORT_ID; } + if (peekOnly) { + size = min_c(bufferSize, msg->size); + if (_msgCode != NULL) + *_msgCode = msg->code; + if (size > 0) + cbuf_memcpy_from_chain(msgBuffer, msg->buffer_chain, 0, size); + RELEASE_PORT_LOCK(sPorts[slot]); + restore_interrupts(state); + release_sem_etc(cachedSem, 1, B_DO_NOT_RESCHEDULE); + // we only peeked, but didn't grab the message + return size; + } + list_remove_link(msg); sPorts[slot].total_count++; @@ -1122,7 +1137,7 @@ writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs, return B_BAD_PORT_ID; } - // store sem_id in local variable + // store sem_id in local variable cachedSem = sPorts[slot].write_sem; RELEASE_PORT_LOCK(sPorts[slot]); @@ -1204,7 +1219,7 @@ writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs, notify_port_select_events(slot, B_EVENT_READ); - // store sem_id in local variable + // store sem_id in local variable cachedSem = sPorts[slot].read_sem; RELEASE_PORT_LOCK(sPorts[slot]);