/* status file name */
#define STATUS_FILE_NAME "pgpool_status"
+/* query cache lock file name */
+#define QUERY_CACHE_LOCK_FILE "memq_lock_file"
+
/* default string used to identify pgpool on syslog output */
#define DEFAULT_SYSLOG_IDENT "pgpool"
POOL_MEMQ_EXCLUSIVE_LOCK,
} POOL_MEMQ_LOCK_TYPE;
-/*
- * File descriptor used for locking in query cache.
- * Inherited to child process.
- */
-extern int memq_lock_fd;
-
extern int pool_hash_init(int nelements);
extern size_t pool_hash_size(int nelements);
extern POOL_CACHEID * pool_hash_search(POOL_QUERY_HASH * key);
*/
volatile SI_ManageInfo *si_manage_info;
-/*
- * File descriptor used for locking in query cache.
- * Inherited to child process.
- */
-int memq_lock_fd;
-
/*
* pgpool main program
*/
free(inet_fds);
}
+ /* For query cache concurrency control */
+ if (pool_config->memory_cache_enabled)
+ {
+ char path[1024];
+ int lfd;
+
+ snprintf(path, sizeof(path), "%s/QUERY_CACHE_LOCK_FILE", pool_config->logdir);
+ lfd = open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
+ if (lfd == -1)
+ {
+ ereport(FATAL,
+ (errmsg("Failed to open lock file for query cache \"%s\"", path),
+ errdetail("%m")));
+ }
+ close(lfd);
+
+ /* Register file unlink at exit */
+ on_proc_exit(FileUnlink, (Datum) path);
+ }
+
/*
* We need to block signal here. Otherwise child might send some signals,
* for example SIGUSR1(fail over). Children will inherit signal blocking
/* Create or write status file */
(void) write_status_file();
- /* For query cache concurrency control */
- if (pool_config->memory_cache_enabled)
- {
- char path[1024];
-
- snprintf(path, sizeof(path), "%s/memq_lock_file", pool_config->logdir);
- memq_lock_fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
- if (memq_lock_fd == -1)
- {
- ereport(FATAL,
- (errmsg("Failed to open lock file for query cache \"%s\"", path),
- errdetail("%m")));
- }
-
- /* Register file unlink at exit */
- on_proc_exit(FileUnlink, (Datum) path);
- }
-
/* This is the main loop */
for (;;)
{
}
#endif
+#undef LOCK_TRACE
+
+static int memq_lock_fd = 0;
+
/*
* Acquire lock: XXX giant lock
*/
void
pool_shmem_lock(POOL_MEMQ_LOCK_TYPE type)
{
+ if (memq_lock_fd == 0)
+ {
+ char path[1024];
+
+ snprintf(path, sizeof(path), "%s/%s", pool_config->logdir, QUERY_CACHE_LOCK_FILE);
+ memq_lock_fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
+ if (memq_lock_fd == -1)
+ {
+ ereport(FATAL,
+ (errmsg("Failed to open lock file for query cache \"%s\"", path),
+ errdetail("%m")));
+ }
+ }
+
+#ifdef LOCK_TRACE
+ elog(LOG, "LOCK TRACE: try to aquire lock %s", type == POOL_MEMQ_EXCLUSIVE_LOCK? "LOCK_EX" : "LOCK_SH");
+#endif
if (pool_is_shmem_cache() && !is_shmem_locked)
{
if (flock(memq_lock_fd, type == POOL_MEMQ_EXCLUSIVE_LOCK? LOCK_EX : LOCK_SH))
ereport(FATAL,
(errmsg("Failed to lock file for query cache"),
errdetail("%m")));
+
}
+
+#ifdef LOCK_TRACE
+ elog(LOG, "LOCK TRACE: aquire lock %s", type == POOL_MEMQ_EXCLUSIVE_LOCK? "LOCK_EX" : "LOCK_SH");
+#endif
is_shmem_locked = true;
}
}
(errmsg("Failed to unlock file for query cache"),
errdetail("%m")));
}
+#ifdef LOCK_TRACE
+ elog(LOG, "LOCK TRACE: unlock");
+#endif
is_shmem_locked = false;
}
}