void s_handle_memcached_event()

in php_memcached_server.c [573:639]


void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg)
{
	int rc;
	short flags = 0;
	php_memc_client_t *client = (php_memc_client_t *) arg;
	memcached_protocol_event_t events;

	if (!client->on_connect_invoked) {
		if (MEMC_HAS_CB(MEMC_SERVER_ON_CONNECT)) {
			zval zremoteip, zremoteport;
			zval params[2];
			protocol_binary_response_status retval;

			struct sockaddr_in addr_in;
			socklen_t addr_in_len = sizeof(addr_in);

			if (getpeername (fd, (struct sockaddr *) &addr_in, &addr_in_len) == 0) {
				ZVAL_STRING(&zremoteip, inet_ntoa (addr_in.sin_addr));
				ZVAL_LONG(&zremoteport, ntohs (addr_in.sin_port));
			} else {
				php_error_docref(NULL, E_WARNING, "getpeername failed: %s", strerror (errno));
				ZVAL_NULL(&zremoteip);
				ZVAL_NULL(&zremoteport);
			}

			ZVAL_COPY(&params[0], &zremoteip);
			ZVAL_COPY(&params[1], &zremoteport);

			retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_CONNECT), params, 2);

			zval_ptr_dtor(&params[0]);
			zval_ptr_dtor(&params[1]);
			zval_ptr_dtor(&zremoteip);
			zval_ptr_dtor(&zremoteport);

			if (retval != PROTOCOL_BINARY_RESPONSE_SUCCESS) {
				memcached_protocol_client_destroy (client->protocol_client);
				efree (client);
				evutil_closesocket (fd);
				return;
			}
		}
		client->on_connect_invoked = 1;
	}

	events = memcached_protocol_client_work (client->protocol_client);

	if (events & MEMCACHED_PROTOCOL_ERROR_EVENT) {
		memcached_protocol_client_destroy (client->protocol_client);
		efree (client);
		evutil_closesocket (fd);
		return;
	}

	if (events & MEMCACHED_PROTOCOL_WRITE_EVENT) {
		flags = EV_WRITE;
	}

	if (events & MEMCACHED_PROTOCOL_READ_EVENT) {
		flags |= EV_READ;
	}

	rc = event_base_once (client->event_base, fd, flags, s_handle_memcached_event, client, NULL);
	if (rc != 0) {
		php_error_docref (NULL, E_WARNING, "Failed to schedule events");
	}
}