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
This commit is contained in:
Ingo Weinhold 2008-09-15 12:59:49 +00:00
parent 68e6763b07
commit b4ec7b8ee5
2 changed files with 30 additions and 6 deletions

View File

@ -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);

View File

@ -23,6 +23,7 @@
#include <sem.h>
#include <syscall_restart.h>
#include <team.h>
#include <util/AutoLock.h>
#include <util/list.h>
#include <wait_for_objects.h>
@ -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]);