int WaylandNativeWindow::readQueue(bool block) { int ret = 0; if (++m_queueReads == 1) { if (block) { ret = wl_display_dispatch_queue(m_display, wl_queue); } else { ret = wl_display_dispatch_queue_pending(m_display, wl_queue); } // all threads waiting on the false branch will wake and return now, so we // can safely set m_queueReads to 0 here instead of relying on every thread // to decrement it. This prevents a race condition when a thread enters readQueue() // before the one in this thread returns. // The new thread would go in the false branch, and there would be no thread in the // true branch, blocking the new thread and any other that will call readQueue in // the future. m_queueReads = 0; pthread_cond_broadcast(&cond); if (ret < 0) { TRACE("wl_display_dispatch_queue returned an error"); check_fatal_error(m_display); return ret; } } else if (block) { while (m_queueReads > 0) { pthread_cond_wait(&cond, &mutex); } } return ret; }
int WaylandNativeWindow::queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd) { WaylandNativeWindowBuffer *wnb = (WaylandNativeWindowBuffer*) buffer; int ret = 0; HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer", "-%p", wnb); lock(); wnb->busy = 1; unlock(); /* XXX locking/something is a bit fishy here */ HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb); while (this->frame_callback && ret != -1) { ret = wl_display_dispatch_queue(m_display, this->wl_queue); } if (ret < 0) { TRACE("wl_display_dispatch_queue returned an error"); HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb); check_fatal_error(m_display); return ret; } HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb); lock(); if (debugenvchecked == 0) { if (getenv("HYBRIS_WAYLAND_DUMP_BUFFERS") != NULL) debugenvchecked = 2; else debugenvchecked = 1; } if (debugenvchecked == 2) { HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_dumping_buffer", "-%p", wnb); hybris_dump_buffer_to_file(wnb->getNativeBuffer()); HYBRIS_TRACE_END("wayland-platform", "queueBuffer_dumping_buffer", "-%p", wnb); } #if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2 HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_waiting_for_fence", "-%p", wnb); sync_wait(fenceFd, -1); close(fenceFd); HYBRIS_TRACE_END("wayland-platform", "queueBuffer_waiting_for_fence", "-%p", wnb); #endif this->frame_callback = wl_surface_frame(m_window->surface); wl_callback_add_listener(this->frame_callback, &frame_listener, this); wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue); if (wnb->wlbuffer == NULL) { wnb->wlbuffer_from_native_handle(m_android_wlegl); TRACE("%p add listener with %p inside", wnb, wnb->wlbuffer); wl_buffer_add_listener(wnb->wlbuffer, &wl_buffer_listener, this); wl_proxy_set_queue((struct wl_proxy *) wnb->wlbuffer, this->wl_queue); } TRACE("%p DAMAGE AREA: %dx%d", wnb, wnb->width, wnb->height); HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_attachdamagecommit", "-resource@%i", wl_proxy_get_id((struct wl_proxy *) wnb->wlbuffer)); wl_surface_attach(m_window->surface, wnb->wlbuffer, 0, 0); wl_surface_damage(m_window->surface, 0, 0, wnb->width, wnb->height); wl_surface_commit(m_window->surface); wl_display_flush(m_display); HYBRIS_TRACE_END("wayland-platform", "queueBuffer_attachdamagecommit", "-resource@%i", wl_proxy_get_id((struct wl_proxy *) wnb->wlbuffer)); //--m_freeBufs; //pthread_cond_signal(&cond); fronted.push_back(wnb); HYBRIS_TRACE_COUNTER("wayland-platform", "fronted.size", "%i", fronted.size()); if (fronted.size() == m_bufList.size()) { HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_wait_for_nonfronted_buffer", "-%p", wnb); /* We have fronted all our buffers, let's wait for one of them to be free */ do { unlock(); ret = wl_display_dispatch_queue(m_display, this->wl_queue); lock(); if (ret == -1) { check_fatal_error(m_display); break; } HYBRIS_TRACE_COUNTER("wayland-platform", "fronted.size", "%i", fronted.size()); if (fronted.size() != m_bufList.size()) break; } while (1); HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_nonfronted_buffer", "-%p", wnb); } HYBRIS_TRACE_END("wayland-platform", "queueBuffer", "-%p", wnb); unlock(); return NO_ERROR; }
int WaylandNativeWindow::postBuffer(ANativeWindowBuffer* buffer) { TRACE(""); WaylandNativeWindowBuffer *wnb = NULL; lock(); std::list<WaylandNativeWindowBuffer *>::iterator it = post_registered.begin(); for (; it != post_registered.end(); it++) { if ((*it)->other == buffer) { wnb = (*it); break; } } unlock(); if (!wnb) { wnb = new WaylandNativeWindowBuffer(buffer); wnb->common.incRef(&wnb->common); buffer->common.incRef(&buffer->common); } int ret = 0; lock(); wnb->busy = 1; unlock(); /* XXX locking/something is a bit fishy here */ while (this->frame_callback && ret != -1) { ret = wl_display_dispatch_queue(m_display, this->wl_queue); } if (ret < 0) { TRACE("wl_display_dispatch_queue returned an error:%i", ret); check_fatal_error(m_display); return ret; } lock(); this->frame_callback = wl_surface_frame(m_window->surface); wl_callback_add_listener(this->frame_callback, &frame_listener, this); wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue); if (wnb->wlbuffer == NULL) { wnb->wlbuffer_from_native_handle(m_android_wlegl); TRACE("%p add listener with %p inside", wnb, wnb->wlbuffer); wl_buffer_add_listener(wnb->wlbuffer, &wl_buffer_listener, this); wl_proxy_set_queue((struct wl_proxy *) wnb->wlbuffer, this->wl_queue); post_registered.push_back(wnb); } TRACE("%p DAMAGE AREA: %dx%d", wnb, wnb->width, wnb->height); wl_surface_attach(m_window->surface, wnb->wlbuffer, 0, 0); wl_surface_damage(m_window->surface, 0, 0, wnb->width, wnb->height); wl_surface_commit(m_window->surface); //--m_freeBufs; //pthread_cond_signal(&cond); posted.push_back(wnb); unlock(); return NO_ERROR; }
/************************************************************************* * * Function: sql_query * * Purpose: Issue a query to the database * *************************************************************************/ static sql_rcode_t sql_query(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config, char const *query) { rlm_sql_postgres_conn_t *conn = handle->conn; int numfields = 0; char *errorcode; char *errormsg; if (!conn->db) { ERROR("rlm_sql_postgresql: Socket not connected"); return RLM_SQL_RECONNECT; } conn->result = PQexec(conn->db, query); /* * Returns a PGresult pointer or possibly a null pointer. * A non-null pointer will generally be returned except in * out-of-memory conditions or serious errors such as inability * to send the command to the server. If a null pointer is * returned, it should be treated like a PGRES_FATAL_ERROR * result. */ if (!conn->result) { ERROR("rlm_sql_postgresql: PostgreSQL Query failed Error: %s", PQerrorMessage(conn->db)); /* As this error COULD be a connection error OR an out-of-memory * condition return value WILL be wrong SOME of the time regardless! * Pick your poison.... */ return RLM_SQL_RECONNECT; } else { ExecStatusType status = PQresultStatus(conn->result); DEBUG("rlm_sql_postgresql: Status: %s", PQresStatus(status)); switch (status){ case PGRES_COMMAND_OK: /*Successful completion of a command returning no data.*/ /*affected_rows function only returns the number of affected rows of a command returning no data... */ conn->affected_rows = affected_rows(conn->result); DEBUG("rlm_sql_postgresql: query affected rows = %i", conn->affected_rows); return 0; break; case PGRES_TUPLES_OK: /*Successful completion of a command returning data (such as a SELECT or SHOW).*/ conn->cur_row = 0; conn->affected_rows = PQntuples(conn->result); numfields = PQnfields(conn->result); /*Check row storing functions..*/ DEBUG("rlm_sql_postgresql: query affected rows = %i , fields = %i", conn->affected_rows, numfields); return 0; break; case PGRES_BAD_RESPONSE: /*The server's response was not understood.*/ DEBUG("rlm_sql_postgresql: Bad Response From Server!!"); return -1; break; case PGRES_NONFATAL_ERROR: /*A nonfatal error (a notice or warning) occurred. Possibly never returns*/ return -1; break; case PGRES_FATAL_ERROR: #if defined(PG_DIAG_SQLSTATE) && defined(PG_DIAG_MESSAGE_PRIMARY) /*A fatal error occurred.*/ errorcode = PQresultErrorField(conn->result, PG_DIAG_SQLSTATE); errormsg = PQresultErrorField(conn->result, PG_DIAG_MESSAGE_PRIMARY); DEBUG("rlm_sql_postgresql: Error %s", errormsg); return check_fatal_error(errorcode); #endif break; default: /* FIXME: An unhandled error occurred.*/ /* PGRES_EMPTY_QUERY PGRES_COPY_OUT PGRES_COPY_IN */ return -1; break; } /* Note to self ... sql_store_result returns 0 anyway after setting the handle->affected_rows.. sql_num_fields returns 0 at worst case which means the check below has a really small chance to return false.. lets remove it then .. yuck!! */ /* } else { if ((sql_store_result(handle, config) == 0) && (sql_num_fields(handle, config) >= 0)) return 0; else return -1; } */ } return -1; }