예제 #1
0
파일: lock.c 프로젝트: thrashaholic/uwsgi
void uwsgi_setup_locking() {

	int i;

	if (uwsgi.locking_setup) return;

	// use the fastest available locking
	if (uwsgi.lock_engine) {
		if (!strcmp(uwsgi.lock_engine, "ipcsem")) {
			uwsgi_log_initial("lock engine: ipcsem\n");
			atexit(uwsgi_ipcsem_clear);
			uwsgi.lock_ops.lock_init = uwsgi_lock_ipcsem_init;
			uwsgi.lock_ops.lock_check = uwsgi_lock_ipcsem_check;
			uwsgi.lock_ops.lock = uwsgi_lock_ipcsem;
			uwsgi.lock_ops.unlock = uwsgi_unlock_ipcsem;
			uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_ipcsem_init;
			uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_ipcsem_check;
			uwsgi.lock_ops.rlock = uwsgi_rlock_ipcsem;
			uwsgi.lock_ops.wlock = uwsgi_wlock_ipcsem;
			uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_ipcsem;
			uwsgi.lock_size = 8;
			uwsgi.rwlock_size = 8;
			goto ready;
		}
		uwsgi_log("unable to find lock engine \"%s\"\n", uwsgi.lock_engine);
		exit(1);
	}

	uwsgi_log_initial("lock engine: %s\n", UWSGI_LOCK_ENGINE_NAME);
#ifdef UWSGI_IPCSEM_ATEXIT
	atexit(uwsgi_ipcsem_clear);
#endif
	uwsgi.lock_ops.lock_init = uwsgi_lock_fast_init;
	uwsgi.lock_ops.lock_check = uwsgi_lock_fast_check;
	uwsgi.lock_ops.lock = uwsgi_lock_fast;
	uwsgi.lock_ops.unlock = uwsgi_unlock_fast;
	uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_fast_init;
	uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_fast_check;
	uwsgi.lock_ops.rlock = uwsgi_rlock_fast;
	uwsgi.lock_ops.wlock = uwsgi_wlock_fast;
	uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_fast;
	uwsgi.lock_size = UWSGI_LOCK_SIZE;
	uwsgi.rwlock_size = UWSGI_RWLOCK_SIZE;

ready:
	// application generic lock
	uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks + 1));
	for (i = 0; i < uwsgi.locks + 1; i++) {
		uwsgi.user_lock[i] = uwsgi_lock_init(uwsgi_concat2("user ", uwsgi_num2str(i)));
	}

	// event queue lock (mitigate same event on multiple queues)
	if (uwsgi.threads > 1) {
		pthread_mutex_init(&uwsgi.thunder_mutex, NULL);
	}

	if (uwsgi.master_process) {
		// signal table lock
		uwsgi.signal_table_lock = uwsgi_lock_init("signal");

		// fmon table lock
		uwsgi.fmon_table_lock = uwsgi_lock_init("filemon");

		// timer table lock
		uwsgi.timer_table_lock = uwsgi_lock_init("timer");

		// rb_timer table lock
		uwsgi.rb_timer_table_lock = uwsgi_lock_init("rbtimer");

		// cron table lock
		uwsgi.cron_table_lock = uwsgi_lock_init("cron");
	}

	if (uwsgi.use_thunder_lock) {
		// process shared thunder lock
		uwsgi.the_thunder_lock = uwsgi_lock_init("thunder");	
	}

	uwsgi.rpc_table_lock = uwsgi_lock_init("rpc");

#ifdef UWSGI_SSL
	// register locking for legions
	struct uwsgi_legion *ul = uwsgi.legions;
	while(ul) {
		ul->lock = uwsgi_lock_init(uwsgi_concat2("legion_", ul->legion));
		ul = ul->next;
	}
#endif
	uwsgi.locking_setup = 1;
}
예제 #2
0
파일: erlang.c 프로젝트: AGoodId/uwsgi
int erlang_init() {

	char *host;
	struct sockaddr_in sin;
	socklen_t slen = sizeof(struct sockaddr_in);
	char *ip = NULL;
	char *nodename;
	struct in_addr addr;

        uerl.lock = uwsgi_lock_init("erlang");

        if (uerl.name) {


		host = strchr(uerl.name, '@');

		if (!host) {
			if (ei_connect_init(&uerl.cnode, uerl.name, uerl.cookie, 0) < 0) {
				uwsgi_log("unable to initialize erlang connection\n");
				exit(1);
			}
		}
		else {
			nodename = uwsgi_concat2n(uerl.name, host-uerl.name, "",0);
			ip = uwsgi_resolve_ip(host+1);
			if (ip) {
#ifdef UWSGI_DEBUG
				uwsgi_log("ip: %s\n", ip);
#endif
				addr.s_addr = inet_addr(ip);
				if (ei_connect_xinit(&uerl.cnode, host+1, nodename, uerl.name, &addr, uerl.cookie, 0) < 0) {
					uwsgi_log("unable to initialize erlang connection\n");
					exit(1);
				}
			}
			else {
				if (ei_connect_init(&uerl.cnode, nodename, uerl.cookie, 0) < 0) {
					uwsgi_log("unable to initialize erlang connection\n");
					exit(1);
				}
			}
			free(nodename);
		}

		if (ip) {
			uerl.fd = bind_to_tcp(ip, uwsgi.listen_queue, NULL);
		}
		else {
			uerl.fd = bind_to_tcp("", uwsgi.listen_queue, NULL);
		}

		if (uerl.fd < 0) {
			exit(1);
		}

        	if (getsockname(uerl.fd, (struct sockaddr *) &sin, &slen)) {
                	uwsgi_error("getsockname()");
			exit(1);
        	}

		if (ei_publish(&uerl.cnode, ntohs(sin.sin_port)) < 0) {
                	uwsgi_log( "*** unable to subscribe with EPMD ***\n");
			exit(1);
		}

		uwsgi_log("Erlang C-Node %s registered on port %d\n", ei_thisnodename(&uerl.cnode), ntohs(sin.sin_port));

	
                if (register_gateway("uWSGI erlang c-node", erlang_loop, NULL) == NULL) {
                        uwsgi_log("unable to register the erlang gateway\n");
                        exit(1);
                }

        }

        return 0;
}
예제 #3
0
파일: lock.c 프로젝트: Nikolo/uwsgi
void uwsgi_setup_locking() {

	int i;

	if (uwsgi.locking_setup) return;

	// use the fastest available locking
	if (uwsgi.lock_engine) {
		if (!strcmp(uwsgi.lock_engine, "ipcsem")) {
			uwsgi_log_initial("lock engine: ipcsem\n");
			atexit(uwsgi_ipcsem_clear);
			uwsgi.lock_ops.lock_init = uwsgi_lock_ipcsem_init;
			uwsgi.lock_ops.lock_check = uwsgi_lock_ipcsem_check;
			uwsgi.lock_ops.lock = uwsgi_lock_ipcsem;
			uwsgi.lock_ops.unlock = uwsgi_unlock_ipcsem;
			uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_ipcsem_init;
			uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_ipcsem_check;
			uwsgi.lock_ops.rlock = uwsgi_rlock_ipcsem;
			uwsgi.lock_ops.wlock = uwsgi_wlock_ipcsem;
			uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_ipcsem;
			uwsgi.lock_size = 8;
			uwsgi.rwlock_size = 8;
			goto ready;
		}
		uwsgi_log("unable to find lock engine \"%s\"\n", uwsgi.lock_engine);
		exit(1);
	}

	uwsgi_log_initial("lock engine: %s\n", UWSGI_LOCK_ENGINE_NAME);
#ifdef UWSGI_IPCSEM_ATEXIT
	atexit(uwsgi_ipcsem_clear);
#endif
	uwsgi.lock_ops.lock_init = uwsgi_lock_fast_init;
	uwsgi.lock_ops.lock_check = uwsgi_lock_fast_check;
	uwsgi.lock_ops.lock = uwsgi_lock_fast;
	uwsgi.lock_ops.unlock = uwsgi_unlock_fast;
	uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_fast_init;
	uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_fast_check;
	uwsgi.lock_ops.rlock = uwsgi_rlock_fast;
	uwsgi.lock_ops.wlock = uwsgi_wlock_fast;
	uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_fast;
	uwsgi.lock_size = UWSGI_LOCK_SIZE;
	uwsgi.rwlock_size = UWSGI_RWLOCK_SIZE;

ready:
	// application generic lock
	uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks + 1));
	for (i = 0; i < uwsgi.locks + 1; i++) {
		char *num = uwsgi_num2str(i);
		uwsgi.user_lock[i] = uwsgi_lock_init(uwsgi_concat2("user ", num));
		free(num);
	}

	// event queue lock (mitigate same event on multiple queues)
	if (uwsgi.threads > 1) {
		pthread_mutex_init(&uwsgi.thunder_mutex, NULL);
	}

	if (uwsgi.master_process) {
		// signal table lock
		uwsgi.signal_table_lock = uwsgi_lock_init("signal");

		// fmon table lock
		uwsgi.fmon_table_lock = uwsgi_lock_init("filemon");

		// timer table lock
		uwsgi.timer_table_lock = uwsgi_lock_init("timer");

		// rb_timer table lock
		uwsgi.rb_timer_table_lock = uwsgi_lock_init("rbtimer");

		// cron table lock
		uwsgi.cron_table_lock = uwsgi_lock_init("cron");
	}

	if (uwsgi.use_thunder_lock) {
		// process shared thunder lock
		uwsgi.the_thunder_lock = uwsgi_lock_init("thunder");	
#ifdef UNBIT
		// we have a serious bug on Unbit (and very probably on older libc)
		// when all of the workers die in the same moment the pthread robust mutes is left
		// in inconsistent state and we have no way to recover
		// we span a thread in the master constantly ensuring the lock is ok
		// for now we apply it only for Unbit (where thunder-lock is automatically enabled)
		uwsgi_robust_mutexes_watchdog();		
#endif
	}

	uwsgi.rpc_table_lock = uwsgi_lock_init("rpc");

#ifdef UWSGI_SSL
	// register locking for legions
	struct uwsgi_legion *ul = uwsgi.legions;
	while(ul) {
		ul->lock = uwsgi_lock_init(uwsgi_concat2("legion_", ul->legion));
		ul = ul->next;
	}
#endif
	uwsgi.locking_setup = 1;
}