From: konn Date: Tue, 6 May 2008 14:50:31 +0000 (+0000) Subject: * Fixed bug. X-Git-Tag: v0.12.20~179 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b9e17fe4d93aeea7fa8743b182a378f0999b302f;p=modchxj%2Fmod_chxj.git * Fixed bug. - for MySQL COOKIE. git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/modchxj/mod_chxj/branches/RELEASE_0_12_0@2624 1a406e8e-add9-4483-a2c8-d8cac5b7c224 --- diff --git a/include/chxj_cookie.h b/include/chxj_cookie.h index b1b51ab3..2b6a4951 100644 --- a/include/chxj_cookie.h +++ b/include/chxj_cookie.h @@ -33,12 +33,15 @@ #define COOKIE_EXPIRE_DB_LOCK_NAME "cookie.expire.db.lock" #define REFERER_COOKIE_KEY "CHXJ_REFER" +#define CHXJ_COOKIE_PROC_MUTEX_FILE "/tmp/chxj_cookie_mutex.lock" /* * default cookie timeout is 30 minute */ #define DEFAULT_COOKIE_TIMEOUT (1800) +extern apr_proc_mutex_t *global_cookie_mutex; + typedef struct cookie_t cookie_t; @@ -113,6 +116,8 @@ extern cookie_t* chxj_update_cookie( cookie_t* old_cookie); extern apr_time_t chxj_parse_cookie_expires(const char *s); +extern int chxj_cookie_lock(request_rec *r); +extern int chxj_cookie_unlock(request_rec *r); #endif /* * vim:ts=2 et diff --git a/include/chxj_dbm.h b/include/chxj_dbm.h index 420210e4..19ae3e48 100644 --- a/include/chxj_dbm.h +++ b/include/chxj_dbm.h @@ -44,4 +44,6 @@ extern int chxj_delete_cookie_dbm(request_rec *r, mod_chxj_config *m, const char extern int chxj_save_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id); extern int chxj_delete_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id); extern int chxj_cookie_expire_gc_dbm(request_rec *r, mod_chxj_config *m); +extern int chxj_cookie_lock_dbm(request_rec *r, mod_chxj_config *m); +extern int chxj_cookie_unlock_dbm(request_rec *r, mod_chxj_config *m); #endif diff --git a/include/chxj_memcache.h b/include/chxj_memcache.h index 7eabcfa7..f1357c62 100644 --- a/include/chxj_memcache.h +++ b/include/chxj_memcache.h @@ -46,5 +46,8 @@ extern int chxj_delete_cookie_memcache(request_rec *r, mod_chxj_config *m, const extern int chxj_save_cookie_expire_memcache(request_rec *r, mod_chxj_config *m, const char *cookie_id); extern int chxj_delete_cookie_expire_memcache(request_rec *r, mod_chxj_config *m, const char *cookie_id); extern int chxj_cookie_expire_gc_memcache(request_rec *r, mod_chxj_config *m); + +extern int chxj_cookie_lock_memcache(request_rec *r, mod_chxj_config *m); +extern int chxj_cookie_unlock_memcache(request_rec *r, mod_chxj_config *m); #endif #endif diff --git a/include/chxj_mysql.h b/include/chxj_mysql.h index 1eae8f0a..bb58c361 100644 --- a/include/chxj_mysql.h +++ b/include/chxj_mysql.h @@ -67,5 +67,8 @@ extern int chxj_delete_cookie_mysql(request_rec *r, mod_chxj_config *m, const ch extern int chxj_save_cookie_expire_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id); extern int chxj_delete_cookie_expire_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id); extern int chxj_cookie_expire_gc_mysql(request_rec *r, mod_chxj_config *m); + +extern int chxj_cookie_lock_mysql(request_rec *r,mod_chxj_config *m); +extern int chxj_cookie_unlock_mysql(request_rec *r, mod_chxj_config *m); #endif #endif diff --git a/include/mod_chxj.h b/include/mod_chxj.h index 1f76a73e..0182a7e9 100644 --- a/include/mod_chxj.h +++ b/include/mod_chxj.h @@ -411,7 +411,7 @@ module AP_MODULE_DECLARE_DATA chxj_module; #define SDBG(X,Y) chxj_log_error(APLOG_MARK,APLOG_DEBUG,0,(X),(Y)) #define PDBG(X,args...) chxj_log_perror(APLOG_MARK,APLOG_DEBUG,0,(apr_pool_t *)(X),##args) #define ERR(X,args...) chxj_log_rerror(APLOG_MARK,APLOG_ERR,0,(X), ##args) -#define SERR(X,Y) chxj_log_error(APLOG_MARK,APLOG_ERR,0,(X),(Y)) +#define SERR(X,args...) chxj_log_error(APLOG_MARK,APLOG_ERR,0,(X),##args) #define PERR(X,args...) chxj_log_perror(APLOG_MARK,APLOG_ERR,0,(apr_pool_t *)(X),##args) #define WRN(rec,format,args...) chxj_log_rerror(APLOG_MARK,APLOG_WARNING,0,(rec),(format), ##args) diff --git a/src/chxj_cookie.c b/src/chxj_cookie.c index f590550c..c289572b 100644 --- a/src/chxj_cookie.c +++ b/src/chxj_cookie.c @@ -50,6 +50,7 @@ static int valid_expires(request_rec *r, const char *value); static int valid_secure(request_rec *r, const char *value); static int check_valid_cookie_attribute(request_rec *r, const char *pair); +apr_proc_mutex_t *global_cookie_mutex; static char * alloc_cookie_id(request_rec *r) @@ -234,7 +235,7 @@ chxj_save_cookie(request_rec *r) cookie->cookie_id = apr_pstrdup(r->pool, old_cookie_id); } else { - DBG(r, "NO LAZY COOKIE save"); + DBG(r, "NO LAZY COOKIE save. old_cookie_id:[%s] LAZY:[%d]", old_cookie_id,IS_COOKIE_LAZY(dconf)); cookie->cookie_id = alloc_cookie_id(r); } @@ -243,7 +244,8 @@ chxj_save_cookie(request_rec *r) #if defined(USE_MYSQL_COOKIE) if (IS_COOKIE_STORE_MYSQL(dconf->cookie_store_type)) { if (! chxj_save_cookie_mysql(r, dconf, cookie->cookie_id, store_string)) { - ERR(r, "faild: chxj_save_cookie_mysql() cookie_id:[%s]", cookie->cookie_id); + ERR(r, "%s:%d faild: chxj_save_cookie_mysql() cookie_id:[%s]", APLOG_MARK,cookie->cookie_id); + cookie = NULL; goto on_error; } done_proc = 1; @@ -252,7 +254,8 @@ chxj_save_cookie(request_rec *r) #if defined(USE_MEMCACHE_COOKIE) if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) { if (! chxj_save_cookie_memcache(r, dconf, cookie->cookie_id, store_string)) { - ERR(r, "failed: chxj_save_cookie_memcache() cookie_id:[%s]", cookie->cookie_id); + ERR(r, "%s:%d failed: chxj_save_cookie_memcache() cookie_id:[%s]", APLOG_MARK, cookie->cookie_id); + cookie = NULL; goto on_error; } done_proc = 1; @@ -260,22 +263,24 @@ chxj_save_cookie(request_rec *r) #endif if (IS_COOKIE_STORE_DBM(dconf->cookie_store_type) || ! done_proc) { if (! chxj_save_cookie_dbm(r, dconf, cookie->cookie_id, store_string)) { - ERR(r, "failed: chxj_save_cookie_dbm() cookie_id:[%s]", cookie->cookie_id); + ERR(r, "%s:%d failed: chxj_save_cookie_dbm() cookie_id:[%s]", APLOG_MARK, cookie->cookie_id); + cookie = NULL; goto on_error; } } } - - chxj_save_cookie_expire(r, cookie); - - + if (cookie) { + chxj_save_cookie_expire(r, cookie); + } on_error: DBG(r, "end chxj_save_cookie()"); return cookie; } + + /* * */ @@ -428,7 +433,7 @@ chxj_load_cookie(request_rec *r, char *cookie_id) #if defined(USE_MYSQL_COOKIE) if (IS_COOKIE_STORE_MYSQL(dconf->cookie_store_type)) { if (! (load_string = chxj_load_cookie_mysql(r, dconf, cookie->cookie_id))) { - ERR(r, "failed: chxj_load_cookie_mysql() cookie_id:[%s]", cookie_id); + ERR(r, "%s:%d failed: chxj_load_cookie_mysql() cookie_id:[%s]", APLOG_MARK, cookie_id); goto on_error0; } done_proc = 1; @@ -437,7 +442,7 @@ chxj_load_cookie(request_rec *r, char *cookie_id) #if defined(USE_MEMCACHE_COOKIE) if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) { if (! (load_string = chxj_load_cookie_memcache(r, dconf, cookie->cookie_id))) { - ERR(r, "failed: chxj_load_cookie_memcache() cookie_id:[%s]", cookie_id); + ERR(r, "%s:%d failed: chxj_load_cookie_memcache() cookie_id:[%s]", APLOG_MARK,cookie_id); goto on_error0; } done_proc = 1; @@ -445,7 +450,7 @@ chxj_load_cookie(request_rec *r, char *cookie_id) #endif if (!done_proc || IS_COOKIE_STORE_DBM(dconf->cookie_store_type)) { if (! (load_string = chxj_load_cookie_dbm(r, dconf, cookie->cookie_id))) { - ERR(r, "failed: chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id); + ERR(r, "%s:%d failed: chxj_load_cookie_dbm() cookie_id:[%s]", APLOG_MARK,cookie_id); goto on_error0; } } @@ -973,6 +978,99 @@ chxj_parse_cookie_expires(const char *s) if (!s) return (apr_time_t)0; return apr_date_parse_rfc(s); } + + +int +chxj_cookie_lock(request_rec *r) +{ + mod_chxj_config *dconf; + apr_status_t rv; + int done_proc = 0; + + DBG(r, "start chxj_cookie_lock()"); + if ((rv = apr_proc_mutex_lock(global_cookie_mutex)) != APR_SUCCESS) { + char errstr[255]; + ERR(r, "%s:%d apr_proc_mutex_lock failure.(%d:%s)", APLOG_MARK, rv, apr_strerror(rv, errstr, 255)); + return 0; + } + dconf = chxj_get_module_config(r->per_dir_config, &chxj_module); +#if defined(USE_MYSQL_COOKIE) + if (IS_COOKIE_STORE_MYSQL(dconf->cookie_store_type)) { + if (! chxj_cookie_lock_mysql(r, dconf)) { + ERR(r, "failed: chxj_cookie_lock_mysql()"); + return 0; + } + done_proc = 1; + } +#endif +#if defined(USE_MEMCACHE_COOKIE) + if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) { + if (! chxj_cookie_lock_memcache(r, dconf)) { + ERR(r, "failed: chxj_cookie_lock_memcache()"); + return 0; + } + done_proc = 1; + } +#endif + if (!done_proc) { + if (! chxj_cookie_lock_dbm(r, dconf)) { + ERR(r, "failed: chxj_cookie_lock_dbm()"); + return 0; + } + } + DBG(r, "end chxj_cookie_lock()"); + return 1; +} + + +int +chxj_cookie_unlock(request_rec *r) +{ + mod_chxj_config *dconf; + int done_proc = 0; + apr_status_t rv; + int rtn = 1; + + DBG(r, "start chxj_cookie_unlock()"); + + dconf = chxj_get_module_config(r->per_dir_config, &chxj_module); +#if defined(USE_MYSQL_COOKIE) + if (IS_COOKIE_STORE_MYSQL(dconf->cookie_store_type)) { + if (! chxj_cookie_unlock_mysql(r, dconf)) { + ERR(r, "failed: chxj_cookie_unlock_mysql()"); + rtn = 0; + goto end_chxj_cookie_unlock; + } + done_proc = 1; + } +#endif +#if defined(USE_MEMCACHE_COOKIE) + if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) { + if (! chxj_cookie_unlock_memcache(r, dconf)) { + ERR(r, "failed: chxj_cookie_unlock_memcache()"); + rtn = 0; + goto end_chxj_cookie_unlock; + } + done_proc = 1; + } +#endif + if (!done_proc) { + if (! chxj_cookie_unlock_dbm(r, dconf)) { + ERR(r, "failed: chxj_cookie_unlock_dbm()"); + rtn = 0; + goto end_chxj_cookie_unlock; + } + } +end_chxj_cookie_unlock: + if ((rv = apr_proc_mutex_unlock(global_cookie_mutex)) != APR_SUCCESS) { + char errstr[255]; + ERR(r, "%s:%d apr_proc_mutex_unlock failure.(%d:%s)", APLOG_MARK, rv, apr_strerror(rv, errstr, 255)); + return 0; + } + DBG(r, "end chxj_cookie_unlock()"); + + return rtn; +} /* * vim:ts=2 et */ diff --git a/src/chxj_dbm.c b/src/chxj_dbm.c index 0a05bb6c..ad354447 100644 --- a/src/chxj_dbm.c +++ b/src/chxj_dbm.c @@ -660,6 +660,20 @@ chxj_cookie_expire_gc_dbm(request_rec *r, mod_chxj_config *m) DBG(r, "end chxj_cookie_expire_gc_dbm()"); return CHXJ_TRUE; } + + +int +chxj_cookie_lock_dbm(request_rec *UNUSED(r), mod_chxj_config *UNUSED(m)) +{ + return 1; /* allways true */ +} + + +int +chxj_cookie_unlock_dbm(request_rec *UNUSED(r), mod_chxj_config *UNUSED(m)) +{ + return 1; /* allways true */ +} /* * vim:ts=2 et */ diff --git a/src/chxj_memcache.c b/src/chxj_memcache.c index bb34af0d..c19a9395 100644 --- a/src/chxj_memcache.c +++ b/src/chxj_memcache.c @@ -39,6 +39,10 @@ #define MEMCACHE_MAX_CONNECTION (1) #define MEMCACHE_TTL_CONNECTION (60) +#define MEMCACHE_LOCK_KEY "chxj::lock" +#define MEMCACHE_WAIT_TIME (1) +#define MEMCACHE_LOCK_RETRY_COUNT (10) + #define MEMCACHE_MAX_SERVER (10) #define MEMCACHE_FLAGS (0) @@ -67,6 +71,7 @@ chxj_memcache_init(request_rec *r, mod_chxj_config *m) if (! mc) { if (!chxj_memcache_and_memcache_server_create(r, m, &st, &mc)) { ERR(r, "failed: chxj_memcache_and_memcache_server_create()"); + DBG(r, "end chxj_memcache_init()"); return CHXJ_FALSE; } apr_pool_cleanup_register(r->pool, (void *)NULL, _memcache_cleanup, _memcache_cleanup); @@ -88,6 +93,7 @@ chxj_memcache_and_memcache_server_create(request_rec *r, mod_chxj_config *m, apr MEMCACHE_TTL_CONNECTION, memcache_server) != APR_SUCCESS) { ERR(r, "failed apr_memcache_server_create() host:[%s] port:[%d]", m->memcache.host, m->memcache.port); + DBG(r, "end chxj_memcache_server_create()"); return CHXJ_FALSE; } DBG(r, "done create_server"); @@ -325,6 +331,58 @@ chxj_cookie_expire_gc_memcache(request_rec *r, mod_chxj_config *UNUSED(m)) return CHXJ_TRUE; } + +int +chxj_cookie_lock_memcache(request_rec *r, mod_chxj_config *m) +{ + char baton[256]; + int retry_count = 0; + apr_uint32_t timeout = (apr_uint32_t) ((m->cookie_timeout) ? m->cookie_timeout : DEFAULT_COOKIE_TIMEOUT); + DBG(r, "start chxj_cookie_lock_memcache()"); + + apr_snprintf(baton, sizeof(baton)-1, "dummy"); + while(1) { + apr_status_t rv = apr_memcache_add(mc, MEMCACHE_LOCK_KEY, baton, strlen(baton), timeout, 0); + if (APR_SUCCESS == rv) { + /* got lock */ + DBG(r, "got lock"); + break; + } + if (rv == APR_EAGAIN) { + continue; + } + retry_count++; + if (retry_count >= MEMCACHE_LOCK_RETRY_COUNT) { + DBG(r, "couldn't get lock"); + return CHXJ_FALSE; + } + sleep(MEMCACHE_WAIT_TIME); + } + + DBG(r, "end chxj_cookie_lock_memcache()"); + return CHXJ_TRUE; +} + + +int +chxj_cookie_unlock_memcache(request_rec *r, mod_chxj_config *UNUSED(m)) +{ + apr_status_t ret; + DBG(r, "start chxj_cookie_unlock_memcache()"); + while(1) { + if ((ret = apr_memcache_delete(mc, MEMCACHE_LOCK_KEY, 0)) != APR_SUCCESS) { + if (ret == APR_EAGAIN) { + continue; + } + ERR(r, "failed: apr_memcache_delete() (lock data) ret:[%d]", ret); + return CHXJ_FALSE; + } + break; + } + DBG(r, "end chxj_cookie_unlock_memcache()"); + return CHXJ_TRUE; +} + #endif /* * vim:ts=2 et diff --git a/src/chxj_mysql.c b/src/chxj_mysql.c index 8f8a5fb5..569fd814 100644 --- a/src/chxj_mysql.c +++ b/src/chxj_mysql.c @@ -70,7 +70,6 @@ chxj_close_mysql_handle() if (connection.handle) { mysql_close(connection.handle); connection.handle = NULL; -{FILE *fp=fopen("/tmp/erer.log","a");fprintf(fp,"%s:%d mysql_close()\n",__FILE__,__LINE__);fclose(fp);} } } @@ -86,11 +85,12 @@ chxj_open_mysql_handle(request_rec *r, mod_chxj_config *m) if (m->mysql.database && strcmp(m->mysql.database, connection.database) == 0) { DBG(r, "already connected"); + DBG(r, "end chxj_open_mysql_handle()"); return 1; } else { if (mysql_select_db(connection.handle,m->mysql.database) != 0) { - ERR(r, "MySQL ERROR: %s", mysql_error(connection.handle)); + ERR(r, "%s:%d MySQL ERROR: %s", APLOG_MARK, mysql_error(connection.handle)); return 0; } else { @@ -105,7 +105,7 @@ chxj_open_mysql_handle(request_rec *r, mod_chxj_config *m) chxj_close_mysql_handle(); connection.handle = mysql_init(&mysql_conn); if (! connection.handle) { - ERR(r, "MySQL ERROR: %s", mysql_error(&mysql_conn)); + ERR(r, "%s:%d MySQL ERROR: %s", APLOG_MARK, mysql_error(&mysql_conn)); return 0; } @@ -124,6 +124,7 @@ chxj_open_mysql_handle(request_rec *r, mod_chxj_config *m) m->mysql.password, m->mysql.port, m->mysql.socket_path); + DBG(r, "end chxj_open_mysql_handle()"); return 0; } @@ -136,7 +137,7 @@ chxj_open_mysql_handle(request_rec *r, mod_chxj_config *m) } if (mysql_select_db(connection.handle,m->mysql.database) != 0) { - ERR(r, "MySQL ERROR: %s", mysql_error(connection.handle)); + ERR(r, "%s:%d MySQL ERROR: %s", APLOG_MARK, mysql_error(connection.handle)); return 0; } @@ -144,11 +145,12 @@ chxj_open_mysql_handle(request_rec *r, mod_chxj_config *m) if (m->mysql.charset) { apr_snprintf(query, sizeof(query)-1, "SET CHARACTER SET %s", m->mysql.charset); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL ERROR: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return 0; } } + DBG(r, "end chxj_open_mysql_handle()"); return 1; } @@ -158,22 +160,28 @@ chxj_mysql_exist_cookie_table(request_rec *r, mod_chxj_config *m) { MYSQL_RES *result; char query[MAX_STRING_LEN]; + int retry_count = 0; apr_snprintf(query, sizeof(query)-1, "desc %s", m->mysql.tablename); DBG(r, "start chxj_mysql_exist_cookie_table() query:[%s]", query); do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle() query:[%s]", query); + ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query); return 0; } connection.reconnect = 0; if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return 0; } } @@ -193,6 +201,7 @@ chxj_mysql_exist_cookie_table_expire(request_rec *r, mod_chxj_config *m) { MYSQL_RES *result; char query[MAX_STRING_LEN]; + int retry_count = 0; apr_snprintf(query, sizeof(query)-1, "desc %s_expire", m->mysql.tablename); @@ -200,17 +209,22 @@ chxj_mysql_exist_cookie_table_expire(request_rec *r, mod_chxj_config *m) do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle() query:[%s]", query); + ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query); return 0; } connection.reconnect = 0; if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return 0; } } while(0); @@ -229,6 +243,7 @@ chxj_mysql_create_cookie_table(request_rec *r, mod_chxj_config *m) { MYSQL_RES *result; char query[MAX_STRING_LEN]; + int retry_count = 0; apr_snprintf(query, sizeof(query)-1, "CREATE TABLE %s (cookie_id VARCHAR(%d) NOT NULL, data TEXT, PRIMARY KEY(cookie_id)) TYPE=InnoDB;", m->mysql.tablename, @@ -236,17 +251,22 @@ chxj_mysql_create_cookie_table(request_rec *r, mod_chxj_config *m) DBG(r, "start chxj_mysql_create_cookie_table() query:[%s]", query); do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle() query:[%s]", query); + ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query); return 0; } connection.reconnect = 0; if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return 0; } } @@ -265,6 +285,7 @@ chxj_mysql_create_cookie_expire_table(request_rec *r, mod_chxj_config *m) { MYSQL_RES *result; char query[MAX_STRING_LEN]; + int retry_count = 0; apr_snprintf(query, sizeof(query)-1, "CREATE TABLE %s_expire (cookie_id VARCHAR(%d) NOT NULL, created_at DATETIME, PRIMARY KEY(cookie_id)) TYPE=InnoDB;", m->mysql.tablename, @@ -274,17 +295,22 @@ chxj_mysql_create_cookie_expire_table(request_rec *r, mod_chxj_config *m) do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle() query:[%s]", query); + ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query); return 0; } connection.reconnect = 0; if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return 0; } } @@ -307,24 +333,30 @@ chxj_mysql_get_cookie_from_cookie_id(request_rec *r, mod_chxj_config *m, const c char *retval = NULL; apr_size_t clen = strlen(cookie_id); char *sql_safe_cookie_id = apr_palloc(r->pool, clen*2+1); + int retry_count = 0; mysql_escape_string(sql_safe_cookie_id,cookie_id,clen); - apr_snprintf(query, sizeof(query)-1, "SELECT data, length(data) FROM %s WHERE cookie_id = '%s' FOR UPDATE;", m->mysql.tablename, sql_safe_cookie_id); + apr_snprintf(query, sizeof(query)-1, "SELECT data, length(data) FROM %s WHERE cookie_id = '%s'", m->mysql.tablename, sql_safe_cookie_id); DBG(r, "start chxj_mysql_get_cookie_from_cookie_id() query:[%s]", query); do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle() query:[%s]", query); + ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query); return 0; } connection.reconnect = 0; if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return NULL; } } @@ -335,8 +367,8 @@ chxj_mysql_get_cookie_from_cookie_id(request_rec *r, mod_chxj_config *m, const c MYSQL_ROW data = mysql_fetch_row(result); int len; if (! data[0]) { - ERR(r, "MySQL cookie_id:[%s] has no valid cookie_id. %s", cookie_id, r->uri); mysql_free_result(result); + ERR(r, "%s:%d MySQL cookie_id:[%s] has no valid cookie_id. %s", APLOG_MARK, cookie_id, r->uri); return NULL; } len = atoi(data[1]); @@ -344,6 +376,7 @@ chxj_mysql_get_cookie_from_cookie_id(request_rec *r, mod_chxj_config *m, const c memcpy(retval, data[0], len); } if (result) mysql_free_result(result); + DBG(r, "end chxj_mysql_get_cookie_from_cookie_id() query:[%s]", query); @@ -359,27 +392,33 @@ chxj_mysql_get_cookie_expire_from_cookie_id(request_rec *r, mod_chxj_config *m, apr_size_t clen = strlen(cookie_id); char *retval = NULL; char *sql_safe_cookie_id = apr_palloc(r->pool, clen*2+1); + int retry_count = 0; mysql_escape_string(sql_safe_cookie_id,cookie_id,clen); - apr_snprintf(query, sizeof(query)-1, "SELECT DATE_FORMAT(created_at, '%%Y%%m%%d%%H%%i%%s') FROM %s_expire WHERE cookie_id = '%s' FOR UPDATE;", + apr_snprintf(query, sizeof(query)-1, "SELECT DATE_FORMAT(created_at, '%%Y%%m%%d%%H%%i%%s') FROM %s_expire WHERE cookie_id = '%s'", m->mysql.tablename, sql_safe_cookie_id); DBG(r, "start chxj_mysql_get_cookie_expire_from_cookie_id() query:[%s]", query); do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle() query:[%s]", query); + ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query); return NULL; } connection.reconnect = 0; if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return NULL; } } @@ -389,8 +428,8 @@ chxj_mysql_get_cookie_expire_from_cookie_id(request_rec *r, mod_chxj_config *m, if (result && (mysql_num_rows(result) >= 1)) { MYSQL_ROW data = mysql_fetch_row(result); if (! data[0]) { - ERR(r, "MySQL cookie_id:[%s] has no valid cookie_id. %s", cookie_id, r->uri); mysql_free_result(result); + ERR(r, "%s:%d MySQL cookie_id:[%s] has no valid cookie_id. %s", APLOG_MARK, cookie_id, r->uri); return NULL; } retval = (char *) apr_palloc(r->pool, 19 + 1); @@ -399,7 +438,7 @@ chxj_mysql_get_cookie_expire_from_cookie_id(request_rec *r, mod_chxj_config *m, } if (result) mysql_free_result(result); - DBG(r, "end chxj_mysql_get_cookie_expire_from_cookie_id() query:[%s]", query); + DBG(r, "end chxj_mysql_get_cookie_expire_from_cookie_id() query:[%s] retval:[%s]", query, retval); return retval; } @@ -412,11 +451,12 @@ chxj_mysql_insert_or_update_cookie(request_rec *r, mod_chxj_config *m, const cha char query[MAX_STRING_LEN]; char *cid = ap_escape_logitem(r->pool, cookie_id); char *cdt = ap_escape_logitem(r->pool, data); + int retry_count = 0; DBG(r, "start chxj_mysql_insert_or_update_cookie() data:[%s]", data); do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle()"); + ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK); return 0; } connection.reconnect = 0; @@ -425,10 +465,15 @@ chxj_mysql_insert_or_update_cookie(request_rec *r, mod_chxj_config *m, const cha if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return 0; } } @@ -439,13 +484,13 @@ chxj_mysql_insert_or_update_cookie(request_rec *r, mod_chxj_config *m, const cha if (mysql_query(connection.handle, query) != 0) { WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); if (!chxj_mysql_get_cookie_from_cookie_id(r, m, cookie_id)) { - ERR(r, "failed chxj_mysql_get_cookie_from_cookie_id() cookie_id:[%s]", cookie_id); + ERR(r, "%s:%d failed chxj_mysql_get_cookie_from_cookie_id() cookie_id:[%s]", APLOG_MARK, cookie_id); return 0; } apr_snprintf(query, sizeof(query)-1, "UPDATE %s set data = '%s' WHERE cookie_id = '%s';", m->mysql.tablename, cdt, cid); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -454,7 +499,7 @@ chxj_mysql_insert_or_update_cookie(request_rec *r, mod_chxj_config *m, const cha apr_snprintf(query, sizeof(query)-1, "COMMIT;"); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -474,12 +519,13 @@ chxj_mysql_insert_or_update_cookie_expire(request_rec *r, mod_chxj_config *m, co MYSQL_RES *result; char query[MAX_STRING_LEN]; char *cid = ap_escape_logitem(r->pool, cookie_id); + int retry_count = 0; DBG(r, "start chxj_mysql_insert_or_update_cookie_expire()"); do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle()"); + ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK); return 0; } connection.reconnect = 0; @@ -488,10 +534,15 @@ chxj_mysql_insert_or_update_cookie_expire(request_rec *r, mod_chxj_config *m, co if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK,mysql_error(connection.handle), r->uri); return 0; } } @@ -502,13 +553,13 @@ chxj_mysql_insert_or_update_cookie_expire(request_rec *r, mod_chxj_config *m, co if (mysql_query(connection.handle, query) != 0) { WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); if (!chxj_mysql_get_cookie_from_cookie_id(r, m, cookie_id)) { - ERR(r, "failed chxj_mysql_get_cookie_from_cookie_id() cookie_id:[%s]", cookie_id); + ERR(r, "%s:%d failed chxj_mysql_get_cookie_from_cookie_id() cookie_id:[%s]", APLOG_MARK, cookie_id); return 0; } apr_snprintf(query, sizeof(query)-1, "UPDATE %s_expire set created_at = localtime WHERE cookie_id = '%s';", m->mysql.tablename, cid); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -517,7 +568,7 @@ chxj_mysql_insert_or_update_cookie_expire(request_rec *r, mod_chxj_config *m, co apr_snprintf(query, sizeof(query)-1, "COMMIT;"); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -541,10 +592,11 @@ chxj_mysql_rollback(request_rec *r, mod_chxj_config *m) apr_snprintf(query, sizeof(query)-1, "ROLLBACK;"); if (!chxj_open_mysql_handle(r, m)) { + DBG(r, "end chxj_mysql_rollback()"); return 1; /* TRUE */ } if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL ERROR: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return 0; /* FALSE */ } DBG(r, "end chxj_mysql_rollback()"); @@ -559,6 +611,7 @@ chxj_mysql_load_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_id apr_size_t clen = strlen(cookie_id); char *retval = NULL; char *sql_safe_cookie_id = apr_palloc(r->pool, clen*2+1); + int retry_count = 0; mysql_escape_string(sql_safe_cookie_id,cookie_id,clen); @@ -568,17 +621,22 @@ chxj_mysql_load_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_id do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle() query:[%s]", query); + ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query); return NULL; } - connection.reconnect = 1; + connection.reconnect = 0; if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri); + return NULL; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return NULL; } } @@ -589,7 +647,7 @@ chxj_mysql_load_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_id MYSQL_ROW data = mysql_fetch_row(result); int len; if (! data[0]) { - ERR(r, "MySQL cookie_id:[%s] has no valid cookie_id. %s", cookie_id, r->uri); + ERR(r, "%s:%d MySQL cookie_id:[%s] has no valid cookie_id. %s", APLOG_MARK, cookie_id, r->uri); mysql_free_result(result); return NULL; } @@ -614,6 +672,7 @@ chxj_mysql_load_cookie_expire(request_rec *r, mod_chxj_config *m, const char *co char *retval = NULL; apr_size_t clen = strlen(cookie_id); char *sql_safe_cookie_id = apr_palloc(r->pool, clen*2+1); + int retry_count = 0; mysql_escape_string(sql_safe_cookie_id,cookie_id,clen); @@ -627,17 +686,22 @@ chxj_mysql_load_cookie_expire(request_rec *r, mod_chxj_config *m, const char *co do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle() query:[%s]", query); + ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK,query); return NULL; } connection.reconnect = 0; if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK,mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return NULL; } } @@ -647,7 +711,7 @@ chxj_mysql_load_cookie_expire(request_rec *r, mod_chxj_config *m, const char *co if (result && (mysql_num_rows(result) >= 1)) { MYSQL_ROW data = mysql_fetch_row(result); if (! data[0]) { - ERR(r, "MySQL cookie_id:[%s] has no valid cookie_id. %s", cookie_id, r->uri); + ERR(r, "%s:%d MySQL cookie_id:[%s] has no valid cookie_id. %s", APLOG_MARK,cookie_id, r->uri); mysql_free_result(result); return NULL; } @@ -668,12 +732,13 @@ chxj_mysql_delete_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_ MYSQL_RES *result; char query[MAX_STRING_LEN]; char *cid = ap_escape_logitem(r->pool, cookie_id); + int retry_count = 0; DBG(r, "start chxj_mysql_delete_cookie() cookie_id:[%s]", cookie_id); do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle()"); + ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK); return 0; } connection.reconnect = 0; @@ -682,23 +747,28 @@ chxj_mysql_delete_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_ if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK,mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return 0; } } while(0); if (!chxj_mysql_get_cookie_from_cookie_id(r, m, cookie_id)) { - ERR(r, "failed chxj_mysql_get_cookie_from_cookie_id() cookie_id:[%s]", cookie_id); + ERR(r, "%s:%d failed chxj_mysql_get_cookie_from_cookie_id() cookie_id:[%s]", APLOG_MARK,cookie_id); return 0; } apr_snprintf(query, sizeof(query)-1, "DELETE FROM %s WHERE cookie_id = '%s';", m->mysql.tablename, cid); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -706,7 +776,7 @@ chxj_mysql_delete_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_ apr_snprintf(query, sizeof(query)-1, "COMMIT;"); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -726,12 +796,13 @@ chxj_mysql_delete_cookie_expire(request_rec *r, mod_chxj_config *m, const char * MYSQL_RES *result; char query[MAX_STRING_LEN]; char *cid = ap_escape_logitem(r->pool, cookie_id); + int retry_count = 0; DBG(r, "start chxj_mysql_delete_cookie_expire() cookie_id:[%s]", cookie_id); do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle()"); + ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK); return 0; } connection.reconnect = 0; @@ -740,23 +811,28 @@ chxj_mysql_delete_cookie_expire(request_rec *r, mod_chxj_config *m, const char * if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK,mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK,mysql_error(connection.handle), r->uri); return 0; } } while(0); if (!chxj_mysql_get_cookie_expire_from_cookie_id(r, m, cookie_id)) { - ERR(r, "failed chxj_mysql_get_cookie_expire_from_cookie_id() cookie_id:[%s]", cookie_id); + ERR(r, "%s:%d failed chxj_mysql_get_cookie_expire_from_cookie_id() cookie_id:[%s]", APLOG_MARK,cookie_id); return 0; } apr_snprintf(query, sizeof(query)-1, "DELETE FROM %s_expire WHERE cookie_id = '%s';", m->mysql.tablename, cid); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK,mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -764,7 +840,7 @@ chxj_mysql_delete_cookie_expire(request_rec *r, mod_chxj_config *m, const char * apr_snprintf(query, sizeof(query)-1, "COMMIT;"); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -783,25 +859,30 @@ chxj_mysql_get_timeout_localtime(request_rec *r, mod_chxj_config *m) MYSQL_RES *result; char query[MAX_STRING_LEN]; char *retval = NULL; + int retry_count = 0; DBG(r, "start chxj_mysql_get_timeout_localtime()"); do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle()"); + ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK); return 0; } connection.reconnect = 0; - apr_snprintf(query, sizeof(query)-1, "SELECT DATE_SUB(localtime, interval %ld second);", (m->cookie_timeout == 0) ? DEFAULT_COOKIE_TIMEOUT : m->cookie_timeout); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return NULL; } } @@ -810,7 +891,7 @@ chxj_mysql_get_timeout_localtime(request_rec *r, mod_chxj_config *m) if (result && (mysql_num_rows(result) >= 1)) { MYSQL_ROW data = mysql_fetch_row(result); if (! data[0]) { - ERR(r, "MySQL ERROR: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); mysql_free_result(result); return NULL; } @@ -831,11 +912,12 @@ chxj_mysql_delete_expired_cookie(request_rec *r, mod_chxj_config *m) MYSQL_RES *result; char query[MAX_STRING_LEN]; char *timeout; + int retry_count = 0; DBG(r, "start chxj_mysql_delete_expired_cookie()"); do { if (!chxj_open_mysql_handle(r, m)) { - ERR(r, "failed chxj_open_mysql_handle()"); + ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK); return 0; } connection.reconnect = 0; @@ -844,10 +926,15 @@ chxj_mysql_delete_expired_cookie(request_rec *r, mod_chxj_config *m) if (mysql_query(connection.handle, query) != 0) { if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) { connection.reconnect = 1; + retry_count++; + if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) { + ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK,mysql_error(connection.handle), r->uri); + return 0; + } sleep(CHXJ_MYSQL_RECONNECT_WAIT_TIME); continue; } - ERR(r, "MySQL ERROR: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK,mysql_error(connection.handle), r->uri); return 0; } } @@ -855,14 +942,14 @@ chxj_mysql_delete_expired_cookie(request_rec *r, mod_chxj_config *m) timeout = chxj_mysql_get_timeout_localtime(r, m); if (! timeout) { - ERR(r, "MySQL ERROR: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); return 0; } apr_snprintf(query, sizeof(query)-1, "SELECT * FROM %s_expire WHERE created_at <= '%s'", m->mysql.tablename, timeout); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK,mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -881,7 +968,7 @@ chxj_mysql_delete_expired_cookie(request_rec *r, mod_chxj_config *m) m->mysql.tablename); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL ERROR: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -897,7 +984,7 @@ chxj_mysql_delete_expired_cookie(request_rec *r, mod_chxj_config *m) timeout); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL ERROR: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -908,7 +995,7 @@ chxj_mysql_delete_expired_cookie(request_rec *r, mod_chxj_config *m) apr_snprintf(query, sizeof(query)-1, "COMMIT;"); DBG(r, "query:[%s]", query); if (mysql_query(connection.handle, query) != 0) { - ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri); chxj_mysql_rollback(r, m); return 0; } @@ -921,11 +1008,22 @@ chxj_mysql_delete_expired_cookie(request_rec *r, mod_chxj_config *m) } + + + + + + + + + int chxj_save_cookie_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string) { + DBG(r, "start chxj_save_cookie_mysql()"); if (! chxj_open_mysql_handle(r, m)) { ERR(r, "Cannot open mysql connection"); + DBG(r, "end chxj_save_cookie_mysql()"); return CHXJ_FALSE; } @@ -933,15 +1031,18 @@ chxj_save_cookie_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id DBG(r, "not found cookie table:[%s]", m->mysql.tablename); if (!chxj_mysql_create_cookie_table(r, m)) { ERR(r, "cannot create cookie table:[%s]", m->mysql.tablename); + DBG(r, "end chxj_save_cookie_mysql()"); return CHXJ_FALSE; } } if (! chxj_mysql_insert_or_update_cookie(r, m, cookie_id, store_string)) { ERR(r, "cannot store to cookie table:[%s]", m->mysql.tablename); + DBG(r, "end chxj_save_cookie_mysql()"); return CHXJ_FALSE; } /* *NEED NOT* close database. */ + DBG(r, "end chxj_save_cookie_mysql()"); return CHXJ_TRUE; } @@ -997,7 +1098,7 @@ chxj_load_cookie_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id } } if (!(load_string = chxj_mysql_load_cookie(r, m, cookie_id))) { - ERR(r, "not found cookie. cookie_id:[%s]", cookie_id); + ERR(r, "%s:%d not found cookie. cookie_id:[%s]", APLOG_MARK, cookie_id); DBG(r, "end chxj_load_cookie_mysql() cookie_id:[%s]", cookie_id); return NULL; } @@ -1013,11 +1114,23 @@ int chxj_delete_cookie_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id) { DBG(r, "start chxj_delete_cookie_mysql() cookie_id=[%s]", cookie_id); - if (!chxj_mysql_delete_cookie(r, m, cookie_id)) { - ERR(r, "failed: chxj_mysql_delete_cookie() cookie_id:[%s]", cookie_id); - DBG(r, "end chxj_delete_cookie_mysql() cookie_id=[%s]", cookie_id); + if (! chxj_open_mysql_handle(r, m)) { + ERR(r, "%s:%d Cannot open mysql connection cookie_id=[%s]", APLOG_MARK, cookie_id); return CHXJ_FALSE; } + if (!chxj_mysql_exist_cookie_table(r, m)) { + DBG(r, "not found cookie table:[%s]", m->mysql.tablename); + if (!chxj_mysql_create_cookie_table(r, m)) { + ERR(r, "%s:%d cannot create cookie table:[%s]", APLOG_MARK, m->mysql.tablename); + return CHXJ_FALSE; + } + } + else { + if (!chxj_mysql_delete_cookie(r, m, cookie_id)) { + ERR(r, "%s:%d failed: chxj_mysql_delete_cookie() cookie_id:[%s]", APLOG_MARK, cookie_id); + return CHXJ_FALSE; + } + } DBG(r, "end chxj_delete_cookie_mysql() cookie_id=[%s]", cookie_id); return CHXJ_TRUE; } @@ -1028,22 +1141,19 @@ chxj_save_cookie_expire_mysql(request_rec *r, mod_chxj_config *m, const char *co { DBG(r, "start chxj_save_cookie_expire_mysql() cookie_id:[%s]", cookie_id); if (! chxj_open_mysql_handle(r, m)) { - ERR(r, "Cannot open mysql connection"); - DBG(r, "end chxj_save_cookie_expire_mysql()"); + ERR(r, "%s:%d Cannot open mysql connection cookie_id=[%s]",APLOG_MARK, cookie_id); return CHXJ_FALSE; } if (!chxj_mysql_exist_cookie_table_expire(r, m)) { DBG(r, "not found cookie table:[%s_expire]", m->mysql.tablename); if (!chxj_mysql_create_cookie_expire_table(r, m)) { - ERR(r, "cannot create cookie table:[%s_expire]", m->mysql.tablename); - DBG(r, "end chxj_save_cookie_expire_mysql()"); + ERR(r, "%s:%d cannot create cookie table:[%s_expire] cookie_id:[%s]", APLOG_MARK, m->mysql.tablename, cookie_id); return CHXJ_FALSE; } } if (! chxj_mysql_insert_or_update_cookie_expire(r, m, cookie_id)) { - ERR(r, "cannot create cookie table:[%s_expire]", m->mysql.tablename); - DBG(r, "end chxj_save_cookie_expire_mysql()"); + ERR(r, "%s:%d cannot create cookie table:[%s_expire] cookie_id:[%s]", APLOG_MARK, m->mysql.tablename, cookie_id); return CHXJ_FALSE; } @@ -1059,11 +1169,23 @@ int chxj_delete_cookie_expire_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id) { DBG(r, "start chxj_delete_cookie_expire_mysql() cookie_id:[%s]", cookie_id); - if (!chxj_mysql_delete_cookie_expire(r, m, cookie_id)) { - ERR(r, "failed: chxj_mysql_delete_cookie() cookie_id:[%s]", cookie_id); - DBG(r, "end chxj_delete_cookie_expire_mysql() cookie_id:[%s]", cookie_id); + if (! chxj_open_mysql_handle(r, m)) { + ERR(r, "%s:%d Cannot open mysql connection", APLOG_MARK); return CHXJ_FALSE; } + + if (!chxj_mysql_exist_cookie_table_expire(r, m)) { + DBG(r, "not found cookie table:[%s_expire]", m->mysql.tablename); + if (!chxj_mysql_create_cookie_expire_table(r, m)) { + ERR(r, "%s:%d cannot create cookie table:[%s_expire] cookie_id:[%s]", APLOG_MARK, m->mysql.tablename, cookie_id); + return CHXJ_FALSE; + } + } else { + if (!chxj_mysql_delete_cookie_expire(r, m, cookie_id)) { + ERR(r, "%s:%d failed: chxj_mysql_delete_cookie() cookie_id:[%s]", APLOG_MARK, cookie_id); + return CHXJ_FALSE; + } + } DBG(r, "end chxj_delete_cookie_expire_mysql() cookie_id:[%s]", cookie_id); return CHXJ_TRUE; } @@ -1073,14 +1195,79 @@ int chxj_cookie_expire_gc_mysql(request_rec *r, mod_chxj_config *m) { DBG(r, "start chxj_cookie_expire_gc_mysql()"); - if (!chxj_mysql_delete_expired_cookie(r, m)) { - ERR(r, "failed: chxj_mysql_delete_expired_cookie()"); - DBG(r, "end chxj_cookie_expire_gc_mysql()"); + if (! chxj_open_mysql_handle(r, m)) { + ERR(r, "Cannot open mysql connection"); + DBG(r, "end chxj_cookie_expire_gc_mysql()"); return CHXJ_FALSE; } + if (!chxj_mysql_exist_cookie_table_expire(r, m)) { + DBG(r, "not found cookie table:[%s_expire]", m->mysql.tablename); + if (!chxj_mysql_create_cookie_expire_table(r, m)) { + ERR(r, "%s:%d cannot create cookie table:[%s_expire]", APLOG_MARK, m->mysql.tablename); + return CHXJ_FALSE; + } + } else { + if (!chxj_mysql_delete_expired_cookie(r, m)) { + ERR(r, "%s:%d failed: chxj_mysql_delete_expired_cookie()", APLOG_MARK); + return CHXJ_FALSE; + } + } DBG(r, "end chxj_cookie_expire_gc_mysql()"); return CHXJ_TRUE; } + + +int +chxj_cookie_lock_mysql(request_rec *r, mod_chxj_config *m) +{ + MYSQL_RES *result; + char query[MAX_STRING_LEN]; + DBG(r, "start chxj_cookie_lock_mysql()"); + if (! chxj_open_mysql_handle(r, m)) { + ERR(r, "Cannot open mysql connection"); + DBG(r, "end chxj_save_cookie_expire_mysql()"); + return CHXJ_FALSE; + } + if (!chxj_mysql_exist_cookie_table_expire(r, m)) { + DBG(r, "not found cookie table:[%s_expire]", m->mysql.tablename); + if (!chxj_mysql_create_cookie_expire_table(r, m)) { + ERR(r, "cannot create cookie table:[%s_expire]", m->mysql.tablename); + DBG(r, "end chxj_cookie_expire_gc_mysql()"); + return CHXJ_FALSE; + } + } + apr_snprintf(query, sizeof(query)-1, "LOCK TABLES %s WRITE", m->mysql.tablename); + DBG(r, "query:[%s]", query); + if (mysql_query(connection.handle, query) != 0) { + chxj_mysql_rollback(r, m); + ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + return CHXJ_FALSE; + } + + result = mysql_store_result(connection.handle); + if (result) mysql_free_result(result); + + DBG(r, "end chxj_cookie_lock_mysql()"); + return CHXJ_TRUE; +} + + +int +chxj_cookie_unlock_mysql(request_rec *r, mod_chxj_config *UNUSED(m)) +{ + char query[MAX_STRING_LEN]; + if (r) DBG(r, "start chxj_cookie_unlock_mysql()"); + apr_snprintf(query, sizeof(query)-1, "UNLOCK TABLES"); + if (mysql_query(connection.handle, query) != 0) { + if (r) { + ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri); + DBG(r, "end chxj_cookie_unlock_mysql()"); + } + return CHXJ_FALSE; + } + if (r) DBG(r, "end chxj_cookie_unlock_mysql()"); + return CHXJ_TRUE; +} #endif /* * vim:ts=2 et diff --git a/src/mod_chxj.c b/src/mod_chxj.c index da82c51f..71e49234 100644 --- a/src/mod_chxj.c +++ b/src/mod_chxj.c @@ -439,11 +439,13 @@ chxj_convert_input_header(request_rec *r,chxjconvrule_entry *entryp) if (strcasecmp(name, CHXJ_COOKIE_PARAM) == 0) { DBG(r, "found cookie parameter[%s]", value); DBG(r, "call start chxj_load_cookie()"); + chxj_cookie_lock(r); cookie = chxj_load_cookie(r, value); DBG(r, "call end chxj_load_cookie()"); if (! no_update_flag && cookie) { chxj_update_cookie(r, cookie); } + chxj_cookie_unlock(r); } } r->args = result; @@ -699,8 +701,10 @@ chxj_output_filter(ap_filter_t *f, apr_bucket_brigade *bb) case CHXJ_SPEC_Chtml_7_0: case CHXJ_SPEC_Jhtml: case CHXJ_SPEC_Jxhtml: + chxj_cookie_lock(r); cookie = chxj_save_cookie(r); s_add_cookie_id_if_has_location_header(r, cookie); + chxj_cookie_unlock(r); break; default: break; @@ -776,6 +780,7 @@ chxj_output_filter(ap_filter_t *f, apr_bucket_brigade *bb) ctx = (mod_chxj_ctx *)f->ctx; DBG(r, "content_type=[%s]", r->content_type); + chxj_cookie_lock(r); if (spec->html_spec_type != CHXJ_SPEC_UNKNOWN && r->content_type @@ -791,19 +796,12 @@ chxj_output_filter(ap_filter_t *f, apr_bucket_brigade *bb) memset(tmp, 0, ctx->len + 1); memcpy(tmp, ctx->buffer, ctx->len); -#if 0 - DBG(r, "input data=[%s] len=[%d]", tmp, ctx->len); -#endif - ctx->buffer = chxj_convert(r, (const char **)&tmp, (apr_size_t *)&ctx->len, spec, user_agent, &cookie); -#if 0 - DBG(r, "output data=[%.*s]", ctx->len,ctx->buffer); -#endif } else { ctx->buffer = apr_psprintf(r->pool, "\n"); @@ -855,6 +853,7 @@ chxj_output_filter(ap_filter_t *f, apr_bucket_brigade *bb) sts = chxj_qrcode_create_image_data(&qrcode, &ctx->buffer, &ctx->len); if (sts != OK) { ERR(r, "qrcode create failed."); + chxj_cookie_unlock(r); return sts; } r->content_type = apr_psprintf(r->pool, "image/jpeg"); @@ -897,10 +896,14 @@ chxj_output_filter(ap_filter_t *f, apr_bucket_brigade *bb) if (ctx->len > 0) { DBG(r, "call pass_data_to_filter()"); s_add_cookie_id_if_has_location_header(r, cookie); + chxj_cookie_unlock(r); rv = pass_data_to_filter(f, (const char *)ctx->buffer, (apr_size_t)ctx->len); } + else { + chxj_cookie_unlock(r); + } f->ctx = NULL; return rv; @@ -923,11 +926,13 @@ chxj_output_filter(ap_filter_t *f, apr_bucket_brigade *bb) case CHXJ_SPEC_Chtml_7_0: case CHXJ_SPEC_Jhtml: case CHXJ_SPEC_Jxhtml: + chxj_cookie_lock(r); cookie = chxj_save_cookie(r); /* * Location Header Check to add cookie parameter. */ s_add_cookie_id_if_has_location_header(r, cookie); + chxj_cookie_unlock(r); break; default: @@ -1188,6 +1193,7 @@ chxj_init_module(apr_pool_t *p, server_rec *s) { void *user_data; + apr_status_t rv; SDBG(s, "start chxj_init_module()"); @@ -1209,7 +1215,11 @@ chxj_init_module(apr_pool_t *p, ap_add_version_component(p, CHXJ_VERSION_PREFIX CHXJ_VERSION); - + if ((rv = apr_proc_mutex_create(&global_cookie_mutex, NULL, APR_LOCK_FCNTL, s->process->pool)) != APR_SUCCESS) { + char errstr[255]; + SERR(s, "%s:%d end chxj_init_module(). mutex create failure.(%d:%s)",APLOG_MARK, rv,apr_strerror(rv,errstr,255)); + return HTTP_INTERNAL_SERVER_ERROR; + } #if 0 conf = (mod_chxj_global_config *)ap_get_module_config(s->module_config, &chxj_module); @@ -1237,9 +1247,12 @@ chxj_init_module(apr_pool_t *p, static void chxj_child_init(apr_pool_t *UNUSED(p), server_rec *s) { - + apr_status_t rv; SDBG(s, "start chxj_child_init()"); - + if ((rv = apr_proc_mutex_child_init(&global_cookie_mutex, NULL, s->process->pool)) != APR_SUCCESS) { + char errstr[255]; + SERR(s, "%s:%d ERROR end chxj_init_module(). mutex create failure.(%d:%s)", APLOG_MARK, rv,apr_strerror(rv,errstr,255)); + } SDBG(s, "end chxj_child_init()"); }