void nsToolkit::RunPump(void* arg) { int32 code; char portname[64]; ThreadInterfaceData id; #ifdef DEBUG printf("TK-RunPump\n"); #endif ThreadInitInfo *info = (ThreadInitInfo*)arg; PR_EnterMonitor(info->monitor); gThreadState = PR_TRUE; PR_Notify(info->monitor); PR_ExitMonitor(info->monitor); delete info; // system wide unique names PR_snprintf(portname, sizeof(portname), "event%lx", (long unsigned) PR_GetCurrentThread()); port_id event = create_port(200, portname); while(read_port_etc(event, &code, &id, sizeof(id), B_TIMEOUT, 1000) >= 0) { MethodInfo *mInfo = (MethodInfo *)id.data; mInfo->Invoke(); if(id.waitingThread != 0) resume_thread(id.waitingThread); delete mInfo; } }
void TVideoPreviewView::ServiceThread() { FUNCTION("TVideoPreviewView::ServiceThread()\n"); while (!mControlQuit) { status_t err=0; int32 code=0; media_message msg; err = read_port_etc(mPort, &code, &msg, sizeof(msg), B_TIMEOUT, 5000); if (err == B_TIMED_OUT) continue; if (err < B_OK) { ERROR("TVideoPreviewView::Run: Unexpected error in read_port(): %lx\n", err); continue; } if (acquire_sem(mServiceLock) == B_NO_ERROR) { if (BMediaNode::HandleMessage(code, &msg, err) && BBufferConsumer::HandleMessage(code, &msg, err)) { BMediaNode::HandleBadMessage(code, &msg, err); } release_sem(mServiceLock); if (code == 0x60000000) /* quit! */ break; } } FUNCTION("TVideoPreviewView::ServiceThread - END\n"); }
int32 ServerApp::controlthread(void *arg) { char data[B_MEDIA_MESSAGE_SIZE]; ServerApp *app; ssize_t size; int32 code; app = (ServerApp *)arg; while ((size = read_port_etc(app->control_port, &code, data, sizeof(data), 0, 0)) > 0) app->HandleMessage(code, data, size); return 0; }
status_t MediaAddonServer::_ControlThread(void* _server) { MediaAddonServer* server = (MediaAddonServer*)_server; char data[B_MEDIA_MESSAGE_SIZE]; ssize_t size; int32 code; while ((size = read_port_etc(server->_ControlPort(), &code, data, sizeof(data), 0, 0)) > 0) server->_HandleMessage(code, data, size); return B_OK; }
status_t HaikuRTSPClient::WaitForInit(bigtime_t timeout) { status_t status = B_ERROR; if (read_port_etc(fInitPort, NULL, &status, sizeof(status), B_RELATIVE_TIMEOUT, timeout) < 0) { return B_ERROR; } close_port(fInitPort); delete_port(fInitPort); fInitPort = -1; return status; }
status_t ServerApp::_ControlThread(void* _server) { ServerApp* server = (ServerApp*)_server; char data[B_MEDIA_MESSAGE_SIZE]; ssize_t size; int32 code; while ((size = read_port_etc(server->_ControlPort(), &code, data, sizeof(data), 0, 0)) > 0) { server->_HandleMessage(code, data, size); } return B_OK; }
status_t LinkReceiver::ReadFromPort(bigtime_t timeout) { // we are here so it means we finished reading the buffer contents ResetBuffer(); status_t err = AdjustReplyBuffer(timeout); if (err < B_OK) return err; int32 code; ssize_t bytesRead; STRACE(("info: LinkReceiver reading port %ld.\n", fReceivePort)); while (true) { if (timeout != B_INFINITE_TIMEOUT) { do { bytesRead = read_port_etc(fReceivePort, &code, fRecvBuffer, fRecvBufferSize, B_TIMEOUT, timeout); } while (bytesRead == B_INTERRUPTED); } else { do { bytesRead = read_port(fReceivePort, &code, fRecvBuffer, fRecvBufferSize); } while (bytesRead == B_INTERRUPTED); } STRACE(("info: LinkReceiver read %ld bytes.\n", bytesRead)); if (bytesRead < B_OK) return bytesRead; // we just ignore incorrect messages, and don't bother our caller if (code != kLinkCode) { STRACE(("wrong port message %lx received.\n", code)); continue; } // port read seems to be valid break; } fDataSize = bytesRead; return B_OK; }
static void haiku_read_pending_debug_events(team_debug_info *teamDebugInfo, bool block, bool (*block_predicate)(void *closure, debug_event *event), void *closure) { while (true) { // read the next message from the debugger port debug_debugger_message_data message; int32 code; ssize_t bytesRead; debug_event *event; // TRACE(("haiku_read_pending_debug_events(): reading from debugger port " // "(%sblocking)...\n", (block ? "" : "non-"))); do { bytesRead = read_port_etc(teamDebugInfo->debugger_port, &code, &message, sizeof(message), (block ? 0 : B_RELATIVE_TIMEOUT), 0); } while (bytesRead == B_INTERRUPTED); if (bytesRead < 0) { if (bytesRead == B_WOULD_BLOCK && !block) break; error("Failed to read from debugger port: %s\n", strerror(bytesRead)); } // TRACE(("haiku_read_pending_debug_events(): got event: %lu, " // "thread: %ld, team: %ld, nub port: %ld\n", code, // message.origin.thread, message.origin.team, // message.origin.nub_port)); // got a message: queue it event = haiku_enqueue_debug_event(&teamDebugInfo->events, code, &message, bytesRead); block = !(*block_predicate)(closure, event); } }
status_t QueryPort(port_id requestPort, int32 msgCode, request_data* request, size_t requestSize, reply_data* reply, size_t replySize) { status_t status = write_port_etc(requestPort, msgCode, request, requestSize, B_RELATIVE_TIMEOUT, TIMEOUT); if (status != B_OK) { ERROR("QueryPort: write_port failed, msgcode 0x%lx, port %ld: %s\n", msgCode, requestPort, strerror(status)); if (status == B_BAD_PORT_ID && requestPort == sMediaServerPort) { find_media_server_port(); requestPort = sMediaServerPort; } else if (status == B_BAD_PORT_ID && requestPort == sMediaAddonServerPort) { find_media_addon_server_port(); requestPort = sMediaAddonServerPort; } else return status; status = write_port_etc(requestPort, msgCode, request, requestSize, B_RELATIVE_TIMEOUT, TIMEOUT); if (status != B_OK) { ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port " "%ld: %s\n", msgCode, requestPort, strerror(status)); return status; } } int32 code; status = read_port_etc(request->reply_port, &code, reply, replySize, B_RELATIVE_TIMEOUT, TIMEOUT); if (status < B_OK) { ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld: %s\n", msgCode, request->reply_port, strerror(status)); } return status < B_OK ? status : reply->result; }
ssize_t _user_read_port_etc(port_id port, int32 *userCode, void *userBuffer, size_t bufferSize, uint32 flags, bigtime_t timeout) { int32 messageCode; ssize_t bytesRead; syscall_restart_handle_timeout_pre(flags, timeout); if (userBuffer == NULL && bufferSize != 0) return B_BAD_VALUE; if ((userCode != NULL && !IS_USER_ADDRESS(userCode)) || (userBuffer != NULL && !IS_USER_ADDRESS(userBuffer))) return B_BAD_ADDRESS; bytesRead = read_port_etc(port, &messageCode, userBuffer, bufferSize, flags | PORT_FLAG_USE_USER_MEMCPY | B_CAN_INTERRUPT, timeout); if (bytesRead >= 0 && userCode != NULL && user_memcpy(userCode, &messageCode, sizeof(int32)) < B_OK) return B_BAD_ADDRESS; return syscall_restart_handle_timeout_post(bytesRead, timeout); }
ssize_t read_port(port_id port, int32* msgCode, void* buffer, size_t bufferSize) { return read_port_etc(port, msgCode, buffer, bufferSize, 0, 0); }
int main() { sSemaphore1 = create_sem(0L, "test semaphore 1"); sSemaphore2 = create_sem(0L, "test semaphore 2"); sPort1 = create_port(2L, "test port 1"); sPort2 = create_port(1L, "test port 2"); printf("semaphore 1: %ld\n", sSemaphore1); printf("semaphore 2: %ld\n", sSemaphore2); printf("port 1: %ld\n", sPort1); printf("port 2: %ld\n", sPort2); thread_id thread = spawn_thread(notifier_thread, "notifier", B_NORMAL_PRIORITY, NULL); resume_thread(thread); printf("thread: %ld\n", thread); object_wait_info initialInfos[] = { { sSemaphore1, B_OBJECT_TYPE_SEMAPHORE, B_EVENT_ACQUIRE_SEMAPHORE }, { sSemaphore2, B_OBJECT_TYPE_SEMAPHORE, B_EVENT_ACQUIRE_SEMAPHORE }, { sPort1, B_OBJECT_TYPE_PORT, B_EVENT_READ }, { sPort2, B_OBJECT_TYPE_PORT, B_EVENT_WRITE }, { 0, B_OBJECT_TYPE_FD, B_EVENT_READ }, { thread, B_OBJECT_TYPE_THREAD, B_EVENT_INVALID } }; int infoCount = sizeof(initialInfos) / sizeof(object_wait_info); while (true) { object_wait_info infos[infoCount]; memcpy(infos, initialInfos, sizeof(initialInfos)); ssize_t result = wait_for_objects_etc(infos, infoCount, B_RELATIVE_TIMEOUT, 10000000LL); if (result >= 0) printf("\nwait_for_objects(): %ld\n", result); else printf("\nwait_for_objects(): %s\n", strerror(result)); print_events(infos, infoCount); for (int i = 0; i < infoCount; i++) { int32 type = infos[i].type; int32 object = infos[i].object; uint16 events = infos[i].events; char buffer[256]; if (type == B_OBJECT_TYPE_SEMAPHORE) { if (events & B_EVENT_ACQUIRE_SEMAPHORE) { status_t error = acquire_sem_etc(object, 1, B_RELATIVE_TIMEOUT, 0); printf("acquire_sem(%ld): %s\n", object, strerror(error)); } } else if (type == B_OBJECT_TYPE_PORT) { if (events & B_EVENT_READ) { int32 code; ssize_t bytesRead = read_port_etc(object, &code, buffer, sizeof(buffer), B_RELATIVE_TIMEOUT, 0); printf("read_port(%ld): %ld\n", object, bytesRead); } if (events & B_EVENT_WRITE) { status_t error = write_port_etc(object, 0xc0de, buffer, 10, B_RELATIVE_TIMEOUT, 0); printf("write_port(%ld): %s\n", object, strerror(error)); } } else if (type == B_OBJECT_TYPE_FD) { if (events & B_EVENT_READ) { ssize_t bytesRead = read(object, buffer, sizeof(buffer)); printf("read(%ld): %ld\n", object, bytesRead); } } else if (type == B_OBJECT_TYPE_THREAD) { if (events & B_EVENT_INVALID) { printf("thread %ld quit\n", object); infoCount--; } } } } return 0; }
/* NOTE: the message code is copied at the beginning of the * given "buffer". "buffer" must be a pointer to a struct {long, void*}. */ status_t read_port(port_id port, int32 *code, void *buffer, size_t bufferSize) { return read_port_etc(port, code, buffer, bufferSize, 0, 0); }