//! Raw data based data exchange with the media_server status_t SendToPort(port_id sendPort, int32 msgCode, command_data* msg, size_t size) { status_t status = write_port_etc(sendPort, msgCode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); if (status != B_OK) { ERROR("SendToPort: write_port failed, msgcode 0x%lx, port %ld: %s\n", msgCode, sendPort, strerror(status)); if (status == B_BAD_PORT_ID && sendPort == sMediaServerPort) { find_media_server_port(); sendPort = sMediaServerPort; } else if (status == B_BAD_PORT_ID && sendPort == sMediaAddonServerPort) { find_media_addon_server_port(); sendPort = sMediaAddonServerPort; } else return status; status = write_port_etc(sendPort, msgCode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); if (status != B_OK) { ERROR("SendToPort: retrying write_port failed, msgCode 0x%lx, " "port %ld: %s\n", msgCode, sendPort, strerror(status)); return status; } } return B_OK; }
// to be used only from a BView or BWindow bool nsToolkit::CallMethodAsync(MethodInfo *info) { #ifdef DEBUG printf("CMA\n"); #endif ThreadInterfaceData id; GetInterface(); id.data = info; id.waitingThread = 0; // Check message count to not exceed the port's capacity. // There seems to be a BeOS bug that allows more // messages on a port than its capacity. port_info portinfo; if (get_port_info(eventport, &portinfo) != B_OK) { return false; } if (port_count(eventport) < portinfo.capacity - 20) { if(write_port_etc(eventport, WM_CALLMETHOD, &id, sizeof(id), B_TIMEOUT, 0) == B_OK) { return true; } } return false; }
// Synchronous version, not in use at the moment bool nsToolkit::CallMethod(MethodInfo *info) { #ifdef DEBUG printf("TK-CM\n"); #endif ThreadInterfaceData id; GetInterface(); id.data = info; id.waitingThread = find_thread(NULL); // Check message count to not exceed the port's capacity. // There seems to be a BeOS bug that allows more // messages on a port than its capacity. port_info portinfo; if (get_port_info(eventport, &portinfo) != B_OK) { return false; } if (port_count(eventport) < portinfo.capacity - 20) { // If we cannot write inside 5 seconds, something is really wrong. if(write_port_etc(eventport, WM_CALLMETHOD, &id, sizeof(id), B_TIMEOUT, 5000000) == B_OK) { // semantics for CallMethod are that it should be synchronous suspend_thread(id.waitingThread); return true; } } return false; }
status_t PostEvent(bluetooth_device* ndev, void* event, size_t size) { struct hci_event_header* outgoingEvent = (struct hci_event_header*) event; status_t err; // Take actions on certain type of events. switch (outgoingEvent->ecode) { case HCI_EVENT_CONN_COMPLETE: { struct hci_ev_conn_complete* data = (struct hci_ev_conn_complete*)(outgoingEvent + 1); // TODO: XXX parse handle field HciConnection* conn = AddConnection(data->handle, BT_ACL, data->bdaddr, ndev->index); if (conn == NULL) panic("no mem for conn desc"); conn->ndevice = ndev; TRACE("%s: Registered connection handle=%#x\n", __func__, data->handle); break; } case HCI_EVENT_DISCONNECTION_COMPLETE: { struct hci_ev_disconnection_complete_reply* data; data = (struct hci_ev_disconnection_complete_reply*) (outgoingEvent + 1); RemoveConnection(data->handle, ndev->index); TRACE("%s: unRegistered connection handle=%#x\n", __func__, data->handle); break; } } // forward to bluetooth server port_id port = find_port(BT_USERLAND_PORT_NAME); if (port != B_NAME_NOT_FOUND) { err = write_port_etc(port, PACK_PORTCODE(BT_EVENT, ndev->index, -1), event, size, B_TIMEOUT, 1 * 1000 * 1000); if (err != B_OK) ERROR("%s: Error posting userland %s\n", __func__, strerror(err)); } else { ERROR("%s: bluetooth_server not found for posting!\n", __func__); err = B_NAME_NOT_FOUND; } return err; }
void BMediaEventLooper::SetEventLatency(bigtime_t latency) { CALLED(); // clamp to a valid value if (latency < 0) latency = 0; fEventLatency = latency; write_port_etc(ControlPort(), GENERAL_PURPOSE_WAKEUP, 0, 0, B_TIMEOUT, 0); }
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; }
status_t LinkSender::Flush(bigtime_t timeout, bool needsReply) { if (fCurrentStatus < B_OK) return fCurrentStatus; EndMessage(needsReply); if (fCurrentStart == 0) return B_OK; STRACE(("info: LinkSender Flush() waiting to send messages of %ld bytes on port %ld.\n", fCurrentEnd, fPort)); status_t err; if (timeout != B_INFINITE_TIMEOUT) { do { err = write_port_etc(fPort, kLinkCode, fBuffer, fCurrentEnd, B_RELATIVE_TIMEOUT, timeout); } while (err == B_INTERRUPTED); } else { do { err = write_port(fPort, kLinkCode, fBuffer, fCurrentEnd); } while (err == B_INTERRUPTED); } if (err < B_OK) { STRACE(("error info: LinkSender Flush() failed for %ld bytes (%s) on port %ld.\n", fCurrentEnd, strerror(err), fPort)); return err; } STRACE(("info: LinkSender Flush() messages total of %ld bytes on port %ld.\n", fCurrentEnd, fPort)); fCurrentEnd = 0; fCurrentStart = 0; return B_OK; }
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; }
/*----------------------------------------------------------------------------*/ status_t write_port(port_id port, int32 code, const void *buffer, size_t bufferSize) { return write_port_etc(port, code, buffer, bufferSize, 0, 0); }