MCPcopy Create free account
hub / github.com/apache/httpd / start_threads

Function start_threads

server/mpm/worker/worker.c:955–1033  ·  view source on GitHub ↗

XXX under some circumstances not understood, children can get stuck * in start_threads forever trying to take over slots which will * never be cleaned up; for now there is an APLOG_DEBUG message issued * every so often when this condition occurs */

Source from the content-addressed store, hash-verified

953 * every so often when this condition occurs
954 */
955static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy)
956{
957 thread_starter *ts = dummy;
958 apr_thread_t **threads = ts->threads;
959 apr_threadattr_t *thread_attr = ts->threadattr;
960 int my_child_num = ts->child_num_arg;
961 proc_info *my_info;
962 apr_status_t rv;
963 int threads_created = 0;
964 int listener_started = 0;
965 int prev_threads_created;
966 int loops, i;
967
968 loops = prev_threads_created = 0;
969 while (1) {
970 /* threads_per_child does not include the listener thread */
971 for (i = 0; i < threads_per_child; i++) {
972 int status = ap_scoreboard_image->servers[my_child_num][i].status;
973
974 if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
975 continue;
976 }
977
978 my_info = (proc_info *)ap_malloc(sizeof(proc_info));
979 my_info->pid = my_child_num;
980 my_info->tid = i;
981 my_info->sd = 0;
982
983 /* We are creating threads right now */
984 ap_update_child_status_from_indexes(my_child_num, i,
985 SERVER_STARTING, NULL);
986 /* We let each thread update its own scoreboard entry. This is
987 * done because it lets us deal with tid better.
988 */
989 rv = ap_thread_create(&threads[i], thread_attr,
990 worker_thread, my_info, pruntime);
991 if (rv != APR_SUCCESS) {
992 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03142)
993 "ap_thread_create: unable to create worker thread");
994 /* let the parent decide how bad this really is */
995 clean_child_exit(APEXIT_CHILDSICK);
996 }
997 threads_created++;
998 }
999 /* Start the listener only when there are workers available */
1000 if (!listener_started && threads_created) {
1001 create_listener_thread(ts);
1002 listener_started = 1;
1003 }
1004 if (start_thread_may_exit || threads_created == threads_per_child) {
1005 break;
1006 }
1007 /* wait for previous generation to clean up an entry */
1008 apr_sleep(apr_time_from_sec(1));
1009 ++loops;
1010 if (loops % 120 == 0) { /* every couple of minutes */
1011 if (prev_threads_created == threads_created) {
1012 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,

Callers

nothing calls this directly

Calls 6

ap_mallocFunction · 0.85
ap_thread_createFunction · 0.85
clean_child_exitFunction · 0.70
create_listener_threadFunction · 0.70
ap_log_errorFunction · 0.50

Tested by

no test coverage detected