in php_memcached.c [796:856]
zend_bool s_invoke_cache_callback(zval *zobject, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_bool with_cas, zend_string *key, zval *value)
{
zend_bool status = 0;
zval params[4];
zval retval;
php_memc_object_t *intern = Z_MEMC_OBJ_P(zobject);
/* Prepare params */
ZVAL_COPY(¶ms[0], zobject);
ZVAL_STR_COPY(¶ms[1], key); /* key */
ZVAL_NEW_REF(¶ms[2], value); /* value */
if (with_cas) {
fci->param_count = 3;
} else {
ZVAL_NEW_EMPTY_REF(¶ms[3]); /* expiration */
ZVAL_NULL(Z_REFVAL(params[3]));
fci->param_count = 4;
}
fci->retval = &retval;
fci->params = params;
if (zend_call_function(fci, fcc) == SUCCESS) {
if (zend_is_true(&retval)) {
time_t expiration;
zval *val = Z_REFVAL(params[2]);
if (with_cas) {
if (Z_TYPE_P(val) == IS_ARRAY) {
zval *rv = zend_hash_str_find(Z_ARRVAL_P(val), "value", sizeof("value") - 1);
if (rv) {
zval *cas = zend_hash_str_find(Z_ARRVAL_P(val), "cas", sizeof("cas") -1);
expiration = cas? Z_LVAL_P(cas) : 0;
status = s_memc_write_zval (intern, MEMC_OP_SET, NULL, key, rv, expiration);
}
/* memleak? zval_ptr_dtor(value); */
ZVAL_COPY(value, val);
}
} else {
expiration = zval_get_long(Z_REFVAL(params[3]));
status = s_memc_write_zval (intern, MEMC_OP_SET, NULL, key, val, expiration);
/* memleak? zval_ptr_dtor(value); */
ZVAL_COPY(value, val);
}
}
}
else {
s_memc_set_status(intern, MEMCACHED_NOTFOUND, 0);
}
zval_ptr_dtor(¶ms[0]);
zval_ptr_dtor(¶ms[1]);
zval_ptr_dtor(¶ms[2]);
if (!with_cas) {
zval_ptr_dtor(¶ms[3]);
}
zval_ptr_dtor(&retval);
return status;
}