void * sge_worker_main(void *arg) { bool do_endlessly = true; cl_thread_settings_t *thread_config = (cl_thread_settings_t*)arg; sge_gdi_ctx_class_t *ctx = NULL; monitoring_t monitor; monitoring_t *monitorp = &monitor; time_t next_prof_output = 0; DENTER(TOP_LAYER, "sge_worker_main"); DPRINTF(("started")); cl_thread_func_startup(thread_config); sge_monitor_init(&monitor, thread_config->thread_name, GDI_EXT, MT_WARNING, MT_ERROR); sge_qmaster_thread_init(&ctx, QMASTER, WORKER_THREAD, true); /* register at profiling module */ set_thread_name(pthread_self(), "Worker Thread"); conf_update_thread_profiling("Worker Thread"); while (do_endlessly) { sge_gdi_packet_class_t *packet = NULL; /* * Wait for packets. As long as packets are available cancelation * of this thread is ignored. The shutdown procedure in the main * thread takes care that packet producers will be terminated * before all worker threads so that this won't be a problem. */ MONITOR_IDLE_TIME( sge_tq_wait_for_task(Master_Task_Queue, 1, SGE_TQ_GDI_PACKET, (void *)&packet), &monitor, mconf_get_monitor_time(), mconf_is_monitor_message()); MONITOR_SET_QLEN((monitorp), sge_tq_get_task_count(Master_Task_Queue)); if (packet != NULL) { sge_gdi_task_class_t *task = packet->first_task; bool is_only_read_request = true; thread_start_stop_profiling(); #ifdef SEND_ANSWER_IN_LISTENER #else /* * prepare buffer for sending an answer */ if (packet->is_intern_request == false && packet->is_gdi_request == true) { init_packbuffer(&(packet->pb), 0, 0); } #endif MONITOR_MESSAGES((monitorp)); if (packet->is_gdi_request == true) { /* * test if a write lock is necessary */ task = packet->first_task; while (task != NULL) { u_long32 command = SGE_GDI_GET_OPERATION(task->command); if (command != SGE_GDI_GET) { is_only_read_request = false; break; } task = task->next; } } else { is_only_read_request = false; } /* * acquire the correct lock */ if (is_only_read_request) { MONITOR_WAIT_TIME(SGE_LOCK(LOCK_GLOBAL, LOCK_READ), monitorp); } else { MONITOR_WAIT_TIME(SGE_LOCK(LOCK_GLOBAL, LOCK_WRITE), monitorp); } if (packet->is_gdi_request == true) { /* * do the GDI request */ task = packet->first_task; while (task != NULL) { sge_c_gdi(ctx, packet, task, &(task->answer_list), &monitor); task = task->next; } } else { task = packet->first_task; sge_c_report(ctx, packet->host, packet->commproc, packet->commproc_id, task->data_list, &monitor); } /* * do unlock */ if (is_only_read_request) { SGE_UNLOCK(LOCK_GLOBAL, LOCK_READ) } else { SGE_UNLOCK(LOCK_GLOBAL, LOCK_WRITE) } if (packet->is_gdi_request == true) { #ifdef SEND_ANSWER_IN_LISTENER sge_gdi_packet_broadcast_that_handled(packet); #else /* * Send the answer to the client */ if (packet->is_intern_request == false) { MONITOR_MESSAGES_OUT(monitorp); sge_gdi2_send_any_request(ctx, 0, NULL, packet->host, packet->commproc, packet->commproc_id, &(packet->pb), TAG_GDI_REQUEST, packet->response_id, NULL); clear_packbuffer(&(packet->pb)); # ifdef BLOCK_LISTENER sge_gdi_packet_broadcast_that_handled(packet); # else sge_gdi_packet_free(&packet); # endif /* * Code only for TS: * * Following if-block will only be executed in testsuite if the qmaster * parameter __TEST_SLEEP_AFTER_REQUEST is defined. This will block the * worker thread if it handled a request. Only this makes sure that * other worker threads can handle incoming requests. Otherwise * it might be possible that one worker threads handles all requests * on fast qmaster hosts if testsuite is not fast enough to generate * gdi requests. */ if (mconf_get_enable_test_sleep_after_request() == true) { sleep(5); } } else { sge_gdi_packet_broadcast_that_handled(packet); /* this is an internal request, packet will get destroyed later, * where the caller waits for the answer * make sure it is no longer accessed here */ packet = NULL; } #endif } else { sge_gdi_packet_free(&packet); } thread_output_profiling("worker thread profiling summary:\n", &next_prof_output); sge_monitor_output(&monitor); } else {
/****** gdi/request_internal/sge_gdi_packet_unpack() ************************* * NAME * sge_gdi_packet_unpack() -- unpacks a GDI packet * * SYNOPSIS * bool * sge_gdi_packet_unpack(sge_gdi_packet_class_t **packet, * lList **answer_list, sge_pack_buffer *pb) * * FUNCTION * This functions unpacks all data representing a single or multi * GDI request. The information is parsed from the given packing * buffer "pb" and ist stored into "packet". Necessary memory will * be allocated. * * INPUTS * sge_gdi_packet_class_t ** packet - new GDI packet * lList **answer_list - answer_list * sge_pack_buffer *pb - packing buffer * * RESULT * bool - error state * true - success * false - error * * NOTES * MT-NOTE: sge_gdi_packet_unpack() is MT safe * * SEE ALSO * gdi/request_internal/sge_gdi_packet_get_pb_size() * gdi/request_internal/sge_gdi_packet_pack_task() * gdi/request_internal/sge_gdi_packet_pack() *******************************************************************************/ bool sge_gdi_packet_unpack(sge_gdi_packet_class_t **packet, lList **answer_list, sge_pack_buffer *pb) { bool aret = true; bool has_next; int pack_ret; DENTER(TOP_LAYER, "sge_gdi_packet_unpack"); *packet = sge_gdi_packet_create_base(answer_list); if (*packet != NULL) { bool first = true; do { u_long32 target = 0; u_long32 command = 0; lList *data_list = NULL; u_long32 version = 0; lList *a_list = NULL; lCondition *condition = NULL; lEnumeration *enumeration = NULL; char *auth_info = NULL; u_long32 task_id = 0; u_long32 packet_id = 0; u_long32 has_next_int = 0; if ((pack_ret = unpackint(pb, &(command)))) { goto error_with_mapping; } if ((pack_ret = unpackint(pb, &(target)))) { goto error_with_mapping; } if ((pack_ret = unpackint(pb, &(version)))) { goto error_with_mapping; } /* JG: TODO (322): At this point we should check the version! ** The existent check function sge_gdi_packet_verify_version ** cannot be called as neccesary data structures are ** available here (e.g. answer list). ** Better do these changes at a more general place ** together with (hopefully coming) further communication ** redesign. */ if ((pack_ret = cull_unpack_list(pb, &(data_list)))) { goto error_with_mapping; } if ((pack_ret = cull_unpack_list(pb, &(a_list)))) { goto error_with_mapping; } if ((pack_ret = cull_unpack_cond(pb, &(condition)))) { goto error_with_mapping; } if ((pack_ret = cull_unpack_enum(pb, &(enumeration)))) { goto error_with_mapping; } if ((pack_ret = unpackstr(pb, &(auth_info)))) { goto error_with_mapping; } if ((pack_ret = unpackint(pb, &(task_id)))) { goto error_with_mapping; } if ((pack_ret = unpackint(pb, &(packet_id)))) { goto error_with_mapping; } if ((pack_ret = unpackint(pb, &has_next_int))) { goto error_with_mapping; } has_next = (has_next_int > 0) ? true : false; if (first) { (*packet)->id = packet_id; (*packet)->version = version; (*packet)->auth_info = auth_info; auth_info = NULL; first = false; } else { auth_info = (char *) sge_free((char *) auth_info); } /* EB: TODO: ST: cleanup - set last parameter to true */ aret = sge_gdi_packet_append_task(*packet, &a_list, target, command, &data_list, &a_list, &condition, &enumeration, false, false); if (aret == false) { goto error; } } while (has_next); } DRETURN(aret); error_with_mapping: aret = sge_gdi_map_pack_errors(pack_ret, answer_list); error: sge_gdi_packet_free(packet); DRETURN(aret); }