int worker_manager(void *data) { for(;;) { int i,j,k; waiter_wait(&manager_monitor); SDL_LockMutex(finished_gen.mutex); while (finished_gen.head != finished_gen.tail) { int h = finished_gen.head; end_procgen(gen_queue[h].world_x, gen_queue[h].world_y); put_chunk_in_cache(gen_queue[h].world_x, gen_queue[h].world_y, gen_queue[h].gc); finished_gen.head = (h+1) % finished_gen.length; } SDL_UnlockMutex(finished_gen.mutex); SDL_LockMutex(requested_mesh_mutex); for (i=0; i < MAX_BUILT_MESHES; ++i) { requested_mesh *rm = &renderer_requested_meshes[i]; if (rm->state == RMS_requested) { int valid_chunks=0; for (k=0; k < 4; ++k) { for (j=0; j < 4; ++j) { if (!rm->chunk_set_valid[k][j]) { int cx = rm->x + j * GEN_CHUNK_SIZE_X, cy = rm->y + k * GEN_CHUNK_SIZE_Y; gen_chunk_cache *gcc = get_gen_chunk_cache_for_coord(cx, cy); if (gcc) { rm->cs.chunk[k][j] = gcc->chunk; } else if (is_in_progress(cx, cy)) { // it's already in progress, so do nothing } else if (can_start_procgen(cx, cy)) { task t; start_procgen(cx,cy); t.world_x = cx; t.world_y = cy; t.task_type = JOB_generate_terrain; add_task(&t); } } else { ++valid_chunks; } } } if (valid_chunks == 16) { task t; t.cs = rm->cs; assert(rm->state == RMS_requested); rm->state = RMS_chunks_completed_waiting_for_meshing; t.task_type = JOB_build_mesh; t.world_x = rm->x; t.world_y = rm->y; add_task(&t); } } } SDL_UnlockMutex(requested_mesh_mutex); } }
static bool wait_for_accept(void) { // accept the connection // wait up to 0.5s struct timespec timeout = {0, 500000000}; for(;;) { int res = waiter_wait(&pfd[ACCEPTING],1,&timeout); if(res < 0) { if(errno == EINTR) { reap_workers(); continue; } if(errno == EAGAIN) { // uh... how? continue; } perror("get_worker wait"); abort(); } return res == 1; // don't waste time hanging in this mini-poll waiting for accept } }