void *platform_tls_get(PLATFORM_TLS_T tls) { void *ret; if (!process_attached) /* TODO: this isn't thread safe */ { vcos_log_trace("Attaching process"); client_process_attach(); process_attached = true; tls = client_tls; vc_vchi_khronos_init(); } ret = vcos_tls_get(tls); if (!ret) { /* The problem here is that on VCFW, the first notification we get that a thread * exists at all is when it calls an arbitrary EGL function. We need to detect this * case and initiliase the per-thread state. * * On Windows this gets done in DllMain. */ client_thread_attach(); vcos_thread_at_exit(client_thread_detach, NULL); ret = vcos_tls_get(tls); } return ret; }
/* wait for a specific message, on the secondary interface * FIXME: does this need to do the nasty waking-up-and-walking-the-queue trick? */ VCOS_MSG_T * vcos_msg_wait_specific(VCOS_MSGQUEUE_T *queue, VCOS_MSG_T *msg) { VCOS_MSG_ENDPOINT_T *self = (VCOS_MSG_ENDPOINT_T *)vcos_tls_get(tls_key); VCOS_MSG_T *reply; (void)queue; vcos_assert(self); reply = vcos_msg_wait_helper(&self->secondary); vcos_assert(reply == msg); /* if this fires, someone is playing fast and loose with sendwait */ (void)msg; return reply; }
/* send on to the target queue, then wait on our secondary queue for the reply */ void vcos_msg_sendwait(VCOS_MSGQUEUE_T *dest, uint32_t code, VCOS_MSG_T *msg) { VCOS_MSG_ENDPOINT_T *self = (VCOS_MSG_ENDPOINT_T *)vcos_tls_get(tls_key); VCOS_MSG_T *reply; vcos_assert(self); vcos_msg_send_helper(&self->secondary, dest, code, msg); reply = vcos_msg_wait_helper(&self->secondary); /* If this fires, then the caller is sending and waiting for multiple things at the same time, * somehow. In that case you need a state machine. */ vcos_assert(reply == msg); (void)reply; }
/** Peek for a message */ VCOS_MSG_T *vcos_msg_peek(void) { VCOS_MSG_ENDPOINT_T *self = (VCOS_MSG_ENDPOINT_T *)vcos_tls_get(tls_key); vcos_assert(self); return vcos_msg_peek_helper(&self->primary); }
void *platform_tls_get_check(PLATFORM_TLS_T tls) { return vcos_tls_get(tls); }