Example #1
0
File: php_set.c Project: Driky/ds
void set_sorted(Set *set, zval *obj)
{
    Set *sorted = set_clone(set);
    htable_sort_by_key(sorted->table);
    set_init_zval_ex(obj, sorted);
}
Example #2
0
static void handle_gc_msg(unsigned code, unsigned gen, int fd, bool isclient) {
    char *source = isclient ? "client" : "worker";
    word_t w;
#if RPT >= 5
    report(5,
"Received GC message with code %u from fd %d (%s), while in state %u",
	   code, fd, source, gc_state);
#endif
    switch (gc_state) {
    case GC_READY:
	if (isclient && code == MSG_GC_START) {
	    /* Garbage collection initiated by client */
#if RPT >= 4
	    report(4, "GC request by client");
#endif
	    do_controller_collect_cmd(0, NULL);
	} else if (!isclient && code == MSG_GC_REQUEST) {
	    if (gen == gc_generation+1) {
#if RPT >= 4
		report(4, "GC request by worker");
#endif
		do_controller_collect_cmd(0, NULL);
	    } else {
#if RPT >= 4
		report(4,
"Outdated (gen = %u, current generation = %u) GC request by worker",
		       gen, gc_generation);
#endif
	    }
	} else {
	    err(false,
		"Unexpected GC message.  Code %u.  In GC_READY state", code);
	}
	break;
    case GC_WAIT_WORKER_START:
	if (code == MSG_GC_START && !isclient) {
	    need_worker_cnt--;
	    if (need_worker_cnt == 0) {
		chunk_ptr msg = msg_new_gc_start();
		set_iterstart(client_fd_set);
		while (set_iternext(client_fd_set, &w)) {
		    int cfd = (int) w;
		    if (!chunk_write(cfd, msg)) {
			err(false,
"Failed to send GC start message to client with fd %d", cfd);
		    }
		}
		chunk_free(msg);
		need_client_fd_set = set_clone(client_fd_set, NULL);
		gc_state = GC_WAIT_CLIENT;
#if RPT >= 3
		report(3, "GC waiting for clients to finish");
#endif
	    }
	} else if (code == MSG_GC_REQUEST) {
#if RPT >= 4
	    report(4,
"GC request by worker while waiting for workers to start.  Ignored.");
#endif
	} else {
	    err(false,
"Unexpected code %u from %s while waiting for workers to start",
		code, source);
	}
	break;
    case GC_WAIT_CLIENT:
	if (code == MSG_GC_FINISH && isclient) {
	    if (set_member(need_client_fd_set, (word_t) fd, true)) {
		if (need_client_fd_set->nelements == 0) {
		    set_free(need_client_fd_set);
		    need_client_fd_set = NULL;
		    chunk_ptr msg = msg_new_gc_finish();
		    set_iterstart(worker_fd_set);
		    while (set_iternext(worker_fd_set, &w)) {
			int wfd = (int) w;
			if (!chunk_write(wfd, msg)) {
			    err(false,
"Failed to send GC Finish message to worker with fd %d", wfd);
			}
		    }
		    chunk_free(msg);
		    gc_state = GC_WAIT_WORKER_FINISH;
#if RPT >= 3
		    report(3, "GC waiting for workers to finish");
#endif
		    need_worker_cnt = worker_fd_set->nelements;
		}
	    } else {
		err(false,
"Got unexpected GC_FINISH message from client with fd %d", fd);
	    }
	} else if (code == MSG_GC_REQUEST) {
#if RPT >= 4
	    report(4,
"GC request by worker while waiting for client.  Ignored.");
#endif
	} else {
	    err(false,
"Unexpected code %u from %s while waiting for clients to finish",
		code, source);
	}
	break;
    case GC_WAIT_WORKER_FINISH:
	if (code == MSG_GC_FINISH && !isclient) {
	    need_worker_cnt--;
	    if (need_worker_cnt == 0) {
		chunk_ptr msg = msg_new_gc_finish();
		set_iterstart(client_fd_set);
		while (set_iternext(client_fd_set, &w)) {
		    int cfd = (int) w;
		    if (!chunk_write(cfd, msg))
			err(false,
"Failed to send GC finish message to client with fd %d", fd);
		}
		chunk_free(msg);
		/* See if there are deferred client connections */
		if (defer_client_fd_set != NULL) {
		    set_iterstart(defer_client_fd_set);
		    while (set_iternext(defer_client_fd_set, &w)) {
			int cfd = (int) w;
			set_insert(client_fd_set, (word_t) cfd);
#if RPT >= 4
			report(4, "Added deferred client with fd %d", cfd);
#endif
			if (need_workers == 0)
			    add_agent(cfd, true);
		    }
		    set_free(defer_client_fd_set);
		    defer_client_fd_set = NULL;
		}
		gc_state = GC_READY;
#if RPT >= 3
		report(3, "GC completed");
#endif
	    }
	} else if (code == MSG_GC_REQUEST) {
#if RPT >= 4
	    report(4,
"GC request by worker while waiting for workers to finish.  Ignored.");
#endif
	} else {
	    err(false,
"Unexpected code %u from %s while waiting for workers to finish",
		code, source);
	}
	break;
    default:
	err(false, "GC in unexpected state %u", gc_state);
    }
}