void chassis_event_handle(int G_GNUC_UNUSED event_fd, short G_GNUC_UNUSED events, void* user_data) { chassis_event_thread_t* thread = user_data; char ping[1]; if (read(thread->notify_receive_fd, ping, 1) != 1) g_log_dbproxy(g_error, "pipes - read error"); network_mysqld_con* client_con = g_async_queue_try_pop(thread->event_queue); if (client_con != NULL) { g_atomic_pointer_add(&(thread->thread_status_var.thread_stat[THREAD_STAT_EVENT_WAITING]), -1); chassis_event_add_connection(NULL, thread, client_con); network_mysqld_con_handle(-1, 0, client_con); } }
/** * add a event asynchronously * * the event is added to the global event-queue and a fd-notification is sent allowing any * of the event-threads to handle it * * @see network_mysqld_con_handle() */ void chassis_event_add(network_mysqld_con* client_con) { //���߳�ִ�У�ping�����̣߳�ʹ����ν���״̬�� chassis* chas = client_con->srv; // choose a event thread static guint last_thread = 1; if (last_thread > chas->event_thread_count) last_thread = 1; chassis_event_thread_t *thread = chas->threads->pdata[last_thread]; ++last_thread; if (TRACE_CON_STATUS(client_con->srv->log->log_trace_modules)) { gchar *msg = g_strdup_printf("connect add to event thread(%d)'s async queue", last_thread - 1); CON_MSG_HANDLE(g_message, client_con, msg); g_free(msg); } g_async_queue_push(thread->event_queue, client_con); g_atomic_pointer_add(&(thread->thread_status_var.thread_stat[THREAD_STAT_EVENT_WAITING]), 1); if (write(thread->notify_send_fd, "", 1) != 1) g_log_dbproxy(g_error, "pipes - write error: %s", g_strerror(errno)); }
/** * g_atomic_pointer_add: * @atomic: a pointer to a #gpointer-sized value * @val: the value to add * * Atomically adds @val to the value of @atomic. * * Think of this operation as an atomic version of * <literal>{ tmp = *atomic; *@atomic += @val; return tmp; }</literal> * * This call acts as a full compiler and hardware memory barrier. * * Returns: the value of @atomic before the add, signed * * Since: 2.30 **/ gssize (g_atomic_pointer_add) (volatile void *atomic, gssize val) { return g_atomic_pointer_add ((volatile gpointer *) atomic, val); }
static CajaOperationResult caja_python_object_update_file_info (CajaInfoProvider *provider, CajaFile *file, GClosure *update_complete, CajaOperationHandle **handle) { CajaPythonObject *object = (CajaPythonObject*)provider; CajaOperationResult ret = CAJA_OPERATION_COMPLETE; PyObject *py_ret = NULL; PyGILState_STATE state = pyg_gil_state_ensure(); static volatile gssize handle_generator = 1; debug_enter(); CHECK_OBJECT(object); *handle = NULL; if (PyObject_HasAttrString(object->instance, "update_file_info_full")) { PyObject *py_handle; void *h; /* Generate a new handle with a default value. */ do { h = (CajaOperationHandle *) g_atomic_pointer_add (&handle_generator, 1); } while (!h); py_handle = caja_python_boxed_new (_PyCajaOperationHandle_Type, h, FALSE); py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX "update_file_info_full", "(NNNN)", pygobject_new((GObject*)provider), py_handle, pyg_boxed_new(G_TYPE_CLOSURE, update_complete, TRUE, TRUE), pygobject_new((GObject*)file)); *handle = (void *) ((PyGBoxed *) py_handle)->boxed; } else if (PyObject_HasAttrString(object->instance, "update_file_info")) { py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX METHOD_NAME, "(N)", pygobject_new((GObject*)file)); } else { goto beach; } HANDLE_RETVAL(py_ret); if (!INT_CHECK(py_ret)) { PyErr_SetString(PyExc_TypeError, METHOD_NAME " must return None or a int"); goto beach; } ret = INT_ASLONG(py_ret); if (!*handle && ret == CAJA_OPERATION_IN_PROGRESS) ret = CAJA_OPERATION_FAILED; beach: free_pygobject_data(file, NULL); Py_XDECREF(py_ret); pyg_gil_state_release(state); return ret; }