diff --git a/config.m4 b/config.m4 index 48efd17..e6a2dfd 100644 --- a/config.m4 +++ b/config.m4 @@ -296,6 +296,28 @@ if test "$PHP_MEMCACHED" != "no"; then AC_MSG_RESULT([no]) fi + ORIG_CFLAGS="$CFLAGS" + ORIG_LIBS="$LIBS" + + CFLAGS="$CFLAGS $PHP_LIBMEMCACHED_INCLUDES" + LIBS="$LIBS $PHP_LIBMEMCACHED_LIBS" + + AC_CACHE_CHECK([whether memcached_exist is defined], ac_cv_have_memcached_exist, [ + AC_TRY_LINK( + [ #include ], + [ memcached_exist (NULL, NULL, 0); ], + [ ac_cv_have_memcached_exist="yes" ], + [ ac_cv_have_memcached_exist="no" ] + ) + ]) + + CFLAGS="$ORIG_CFLAGS" + LIBS="$ORIG_LIBS" + + if test "$ac_cv_have_memcached_exist" = "yes"; then + AC_DEFINE(HAVE_MEMCACHED_EXIST, [1], [Whether memcached_exist is defined]) + fi + PHP_MEMCACHED_FILES="php_memcached.c php_libmemcached_compat.c g_fmt.c" if test "$PHP_SYSTEM_FASTLZ" != "no"; then diff --git a/php_memcached.c b/php_memcached.c index f5a9ea2..6f4ae3b 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -332,6 +332,25 @@ static void php_memc_destroy(struct memc_obj *m_obj, zend_bool persistent); ****************************************/ +memcached_return php_memcached_exist (memcached_st *memc, zend_string *key) +{ +#ifdef HAVE_MEMCACHED_EXIST + return memcached_exist (memc, key->val, key->len); +#else + memcached_return rc = MEMCACHED_SUCCESS; + uint32_t flags = 0; + size_t value_length = 0; + char *value = NULL; + + value = memcached_get (memc, key->val, key->len, &value_length, &flags, &rc); + if (value) { + free (value); + } + return rc; +#endif +} + + char *php_memc_printable_func (zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) { char *buffer = NULL; diff --git a/php_memcached_private.h b/php_memcached_private.h index 2929818..ffca963 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -192,6 +192,8 @@ int php_memc_sess_list_entry(void); char *php_memc_printable_func (zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC); +memcached_return php_memcached_exist (memcached_st *memc, zend_string *key); + #endif /* PHP_MEMCACHED_PRIVATE_H */ /* diff --git a/php_memcached_session.c b/php_memcached_session.c index 5f66e41..85baad0 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -277,7 +277,7 @@ success: PS_CLOSE_FUNC(memcached) { memcached_sess *memc_sess = PS_GET_MOD_DATA(); - + if (!memc_sess) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session is not allocated, check session.save_path value"); return FAILURE; @@ -336,8 +336,9 @@ PS_READ_FUNC(memcached) *val = zend_string_init(payload, payload_len, 1); free(payload); return SUCCESS; - } else if (status = MEMCACHED_NOTFOUND) { + } else if (status == MEMCACHED_NOTFOUND) { *val = ZSTR_EMPTY_ALLOC(); + return SUCCESS; } else { return FAILURE; } @@ -351,7 +352,7 @@ PS_WRITE_FUNC(memcached) memcached_return status; memcached_sess *memc_sess = PS_GET_MOD_DATA(); size_t key_length; - + if (!memc_sess) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session is not allocated, check session.save_path value"); return FAILURE; @@ -409,39 +410,34 @@ PS_GC_FUNC(memcached) PS_CREATE_SID_FUNC(memcached) { zend_string *sid; - int maxfail = 3; + int retries = 3; memcached_sess *memc_sess = PS_GET_MOD_DATA(); + time_t expiration = PS(gc_maxlifetime); - do { + if (!memc_sess) { + return NULL; + } + + while (retries-- > 0) { sid = php_session_create_id((void**)&memc_sess); - if (!sid) { - if (--maxfail < 0) { - return NULL; - } else { - continue; - } - } - /* Check collision */ - /* FIXME: mod_data(memc_sess) should not be NULL (User handler could be NULL) */ - if (memc_sess && memcached_exist(memc_sess->memc_sess, sid->val, sid->len) == MEMCACHED_SUCCESS) { - if (sid) { - zend_string_release(sid); - sid = NULL; - } - if (--maxfail < 0) { - return NULL; - } - } - } while(!sid); - return sid; + if (sid) { + if (memcached_add(memc_sess->memc_sess, sid->val, sid->len, "0", 0, expiration, 0) == MEMCACHED_SUCCESS) { + return sid; + } + else { + zend_string_release(sid); + } + } + } + return NULL; } PS_VALIDATE_SID_FUNC(memcached) { memcached_sess *memc_sess = PS_GET_MOD_DATA(); - if (memcached_exist(memc_sess->memc_sess, key->val, key->len) == MEMCACHED_SUCCESS) { + if (php_memcached_exist(memc_sess->memc_sess, key) == MEMCACHED_SUCCESS) { return SUCCESS; } else { return FAILURE;