Worker* worker_new(Slave* slave) { /* make sure this isnt called twice on the same thread! */ utility_assert(!worker_isAlive()); Worker* worker = g_new0(Worker, 1); MAGIC_INIT(worker); worker->slave = slave; worker->thread_id = slave_generateWorkerID(slave); worker->clock_now = SIMTIME_INVALID; worker->clock_last = SIMTIME_INVALID; worker->clock_barrier = SIMTIME_INVALID; /* each worker needs a private copy of each plug-in library */ worker->privatePrograms = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, (GDestroyNotify)program_free); if(slave_getWorkerCount(slave) <= 1) { /* this will cause events to get pushed to this queue instead of host queues */ worker->serialEventQueue = eventqueue_new(); } g_private_replace(&workerKey, worker); return worker; }
static struct oio_ext_local_s * _local_ensure (void) { struct oio_ext_local_s *l = _local_get (); if (!l) { l = g_malloc0 (sizeof(*l)); g_private_replace (&th_local_key, l); } return l; }
void oio_ext_set_reqid (const char *reqid) { g_private_replace (&th_local_key_reqid, g_strdup (reqid)); }
void bt_request_processor(void *job_params, void *pool_params) { static GPrivate redis_key = G_PRIVATE_INIT(bt_free_redis); /* Data to be sent to the client. */ bt_response_buffer_t *resp_buffer = NULL; /* Basic request data. */ bt_req_t request; /* Message to be sent to the client in case of error. */ char *error = NULL; /* Cast parameters to their correct types. */ bt_job_params_t *params = (bt_job_params_t *) job_params; bt_config_t *config = (bt_config_t *) pool_params; /* Fills object with data in buffer. */ bt_read_request_data(params->buff, &request); int redis_timeout = config->redis_timeout * 1000; redisContext *redis = g_private_get(&redis_key); /* Connects to the Redis instance where the data should be stored. */ if (!redis) { redis_connect: redis = bt_redis_connect(config->redis_socket_path, config->redis_host, config->redis_port, redis_timeout, config->redis_db); /* Cannot connect, answer this request with an error. */ if (!redis) { error = "Tracker temporarily unavailable: data storage is not working"; request.action = BT_ACTION_ERROR; } /* Stores the new redis context in thread local storage. */ g_private_replace(&redis_key, redis); } else { if (!bt_redis_ping(redis)) { goto redis_connect; } } /* Dispatches the request to the appropriate handler function. */ switch (request.action) { case BT_ACTION_CONNECT: resp_buffer = bt_handle_connection(&request, config, params->buflen, redis); break; case BT_ACTION_ANNOUNCE: resp_buffer = bt_handle_announce(&request, config, params->buff, params->buflen, params->from_addr, redis); break; case BT_ACTION_SCRAPE: resp_buffer = bt_handle_scrape(&request, config, params->buff, params->buflen, redis); break; case BT_ACTION_ERROR: resp_buffer = bt_send_error(&request, error); break; } if (resp_buffer != NULL) { syslog(LOG_DEBUG, "Sending response back to the client"); if (sendto(params->sock, resp_buffer->data, resp_buffer->length, 0, (struct sockaddr *) params->from_addr, params->from_addr_len) == -1) { syslog(LOG_ERR, "Error in sendto()"); } /* Destroys response data. */ free(resp_buffer->data); free(resp_buffer); } /* Frees the cloned input buffer. */ free(params->buff); free(params); }
static inline void g_module_set_error_unduped (gchar *error) { g_private_replace (&module_error_private, error); errno = 0; }