in php_memcached.c [1214:1333]
static PHP_METHOD(Memcached, __construct)
{
php_memc_object_t *intern;
php_memc_user_data_t *memc_user_data;
zend_string *persistent_id = NULL;
zend_string *conn_str = NULL;
zend_string *plist_key = NULL;
zend_fcall_info fci = {0};
zend_fcall_info_cache fci_cache;
zend_bool is_persistent = 0;
/* "|S!f!S" */
ZEND_PARSE_PARAMETERS_START(0, 3)
Z_PARAM_OPTIONAL
Z_PARAM_STR_EX(persistent_id, 1, 0)
Z_PARAM_FUNC_EX(fci, fci_cache, 1, 0)
Z_PARAM_STR(conn_str)
ZEND_PARSE_PARAMETERS_END();
intern = Z_MEMC_OBJ_P(getThis());
intern->is_pristine = 1;
if (persistent_id && persistent_id->len) {
zend_resource *le;
plist_key = zend_string_alloc(sizeof("memcached:id=") + persistent_id->len - 1, 0);
snprintf(ZSTR_VAL(plist_key), plist_key->len + 1, "memcached:id=%s", ZSTR_VAL(persistent_id));
if ((le = zend_hash_find_ptr(&EG(persistent_list), plist_key)) != NULL) {
if (le->type == php_memc_list_entry()) {
intern->memc = le->ptr;
intern->is_pristine = 0;
zend_string_release (plist_key);
return;
}
}
is_persistent = 1;
}
if (conn_str && conn_str->len > 0) {
intern->memc = memcached (ZSTR_VAL(conn_str), ZSTR_LEN(conn_str));
}
else {
intern->memc = memcached (NULL, 0);
}
if (!intern->memc) {
php_error_docref(NULL, E_ERROR, "Failed to allocate memory for memcached structure");
/* never reached */
}
memc_user_data = pecalloc (1, sizeof(*memc_user_data), is_persistent);
memc_user_data->serializer = MEMC_G(serializer_type);
memc_user_data->compression_type = MEMC_G(compression_type);
memc_user_data->compression_enabled = 1;
memc_user_data->encoding_enabled = 0;
memc_user_data->store_retry_count = MEMC_G(store_retry_count);
memc_user_data->set_udf_flags = -1;
memc_user_data->is_persistent = is_persistent;
memcached_set_user_data(intern->memc, memc_user_data);
/* Set default behaviors */
if (MEMC_G(default_behavior.consistent_hash_enabled)) {
memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT);
if (rc != MEMCACHED_SUCCESS) {
php_error_docref(NULL, E_WARNING, "Failed to turn on consistent hash: %s", memcached_strerror(intern->memc, rc));
}
}
if (MEMC_G(default_behavior.binary_protocol_enabled)) {
memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
if (rc != MEMCACHED_SUCCESS) {
php_error_docref(NULL, E_WARNING, "Failed to turn on binary protocol: %s", memcached_strerror(intern->memc, rc));
}
}
if (MEMC_G(default_behavior.connect_timeout)) {
memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, MEMC_G(default_behavior.connect_timeout));
if (rc != MEMCACHED_SUCCESS) {
php_error_docref(NULL, E_WARNING, "Failed to set connect timeout: %s", memcached_strerror(intern->memc, rc));
}
}
if (fci.size) {
if (!s_invoke_new_instance_cb(getThis(), &fci, &fci_cache, persistent_id) || EG(exception)) {
/* error calling or exception thrown from callback */
if (plist_key) {
zend_string_release(plist_key);
}
/*
Setting intern->memc null prevents object destruction from freeing the memcached_st
We free it manually here because it might be persistent and has not been
registered to persistent_list yet
*/
php_memc_destroy(intern->memc, memc_user_data);
intern->memc = NULL;
return;
}
}
if (plist_key) {
zend_resource le;
le.type = php_memc_list_entry();
le.ptr = intern->memc;
GC_SET_REFCOUNT(&le, 1);
/* plist_key is not a persistent allocated key, thus we use str_update here */
if (zend_hash_str_update_mem(&EG(persistent_list), ZSTR_VAL(plist_key), ZSTR_LEN(plist_key), &le, sizeof(le)) == NULL) {
zend_string_release(plist_key);
php_error_docref(NULL, E_ERROR, "could not register persistent entry");
/* not reached */
}
zend_string_release(plist_key);
}
}