summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2023-08-03 10:37:12 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2023-08-03 10:37:12 +0200
commitd9a54c3f6cbf068a1e1553eac9adcf9127b007f5 (patch)
treee7e8cb1beda5ae9ba83a53d0cea4a29379b6e6a6
parent6d6365d782a713d7fde48daa70e64e64ac283001 (diff)
downloadpgfuse-d9a54c3f6cbf068a1e1553eac9adcf9127b007f5.tar.gz
pgfuse-d9a54c3f6cbf068a1e1553eac9adcf9127b007f5.tar.bz2
fixing for platforms, where pthread_t is not numeric (as for musl, where it is a pointer,
POSIX sadly did away with the requirement that pthread_t must be a numeric): - printing thread ids as pointers with '%p' instead of converting them to unsigned int and printing them with '%u' - using separate 'avail' and 'thread' arrays in pools to record status of pooled database connections
-rw-r--r--pgfuse.c80
-rw-r--r--pool.c46
-rw-r--r--pool.h3
3 files changed, 74 insertions, 55 deletions
diff --git a/pgfuse.c b/pgfuse.c
index e99fc7f..572fd31 100644
--- a/pgfuse.c
+++ b/pgfuse.c
@@ -107,7 +107,7 @@ static int psql_release( PgFuseData *data, PGconn *conn )
#define RELEASE( C ) \
if( psql_release( data, C ) < 0 ) return -EIO;
-#define THREAD_ID (unsigned int)pthread_self( )
+#define THREAD_ID pthread_self( )
/* --- other helpers --- */
@@ -149,7 +149,7 @@ static void *pgfuse_init( struct fuse_conn_info *conn )
{
PgFuseData *data = (PgFuseData *)fuse_get_context( )->private_data;
- syslog( LOG_INFO, "Mounting file system on '%s' ('%s', %s, %s), thread #%u",
+ syslog( LOG_INFO, "Mounting file system on '%s' ('%s', %s, %s), thread %p",
data->mountpoint, data->conninfo,
data->read_only ? "read-only" : "read-write",
data->noatime ? "noatime" : "atime",
@@ -181,7 +181,7 @@ static void pgfuse_destroy( void *userdata )
{
PgFuseData *data = (PgFuseData *)userdata;
- syslog( LOG_INFO, "Unmounting file system on '%s' (%s), thread #%u",
+ syslog( LOG_INFO, "Unmounting file system on '%s' (%s), thread %p",
data->mountpoint, data->conninfo, THREAD_ID );
if( !data->multi_threaded ) {
@@ -217,7 +217,7 @@ static int pgfuse_fgetattr( const char *path, struct stat *stbuf, struct fuse_fi
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "FgetAttrs '%s' on '%s', thread #%u",
+ syslog( LOG_INFO, "FgetAttrs '%s' on '%s', thread %p",
path, data->mountpoint, THREAD_ID );
}
@@ -233,7 +233,7 @@ static int pgfuse_fgetattr( const char *path, struct stat *stbuf, struct fuse_fi
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id for %s '%s' is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Id for %s '%s' is %"PRIi64", thread %p",
S_ISDIR( meta.mode ) ? "dir" : "file", path, id,
THREAD_ID );
}
@@ -253,7 +253,7 @@ static int pgfuse_getattr( const char *path, struct stat *stbuf )
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "GetAttrs '%s' on '%s', thread #%u",
+ syslog( LOG_INFO, "GetAttrs '%s' on '%s', thread %p",
path, data->mountpoint, THREAD_ID );
}
@@ -269,7 +269,7 @@ static int pgfuse_getattr( const char *path, struct stat *stbuf )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id for %s '%s' is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Id for %s '%s' is %"PRIi64", thread %p",
S_ISDIR( meta.mode ) ? "dir" : "file", path, id,
THREAD_ID );
}
@@ -286,7 +286,7 @@ static int pgfuse_access( const char *path, int mode )
PgFuseData *data = (PgFuseData *)fuse_get_context( )->private_data;
if( data->verbose ) {
- syslog( LOG_INFO, "Access on '%s' and mode '%o, thread #%u",
+ syslog( LOG_INFO, "Access on '%s' and mode '%o, thread %p",
path, (unsigned int)mode, THREAD_ID );
}
@@ -350,7 +350,7 @@ static int pgfuse_create( const char *path, mode_t mode, struct fuse_file_info *
if( data->verbose ) {
char *s = flags_to_string( fi->flags );
- syslog( LOG_INFO, "Create '%s' in mode '%o' on '%s' with flags '%s', thread #%u",
+ syslog( LOG_INFO, "Create '%s' in mode '%o' on '%s' with flags '%s', thread %p",
path, mode, data->mountpoint, s, THREAD_ID );
if( *s != '<' ) free( s );
}
@@ -371,7 +371,7 @@ static int pgfuse_create( const char *path, mode_t mode, struct fuse_file_info *
if( id >= 0 ) {
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id for dir '%s' is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Id for dir '%s' is %"PRIi64", thread %p",
path, id, THREAD_ID );
}
@@ -420,7 +420,7 @@ static int pgfuse_create( const char *path, mode_t mode, struct fuse_file_info *
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Parent_id for new file '%s' in dir '%s' is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Parent_id for new file '%s' in dir '%s' is %"PRIi64", thread %p",
path, parent_path, parent_id, THREAD_ID );
}
@@ -458,7 +458,7 @@ static int pgfuse_create( const char *path, mode_t mode, struct fuse_file_info *
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id for new file '%s' is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Id for new file '%s' is %"PRIi64", thread %p",
path, id, THREAD_ID );
}
@@ -482,7 +482,7 @@ static int pgfuse_open( const char *path, struct fuse_file_info *fi )
if( data->verbose ) {
char *s = flags_to_string( fi->flags );
- syslog( LOG_INFO, "Open '%s' on '%s' with flags '%s', thread #%u",
+ syslog( LOG_INFO, "Open '%s' on '%s' with flags '%s', thread %p",
path, data->mountpoint, s, THREAD_ID );
if( *s != '<' ) free( s );
}
@@ -497,7 +497,7 @@ static int pgfuse_open( const char *path, struct fuse_file_info *fi )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id for file '%s' to open is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Id for file '%s' to open is %"PRIi64", thread %p",
path, id, THREAD_ID );
}
@@ -546,7 +546,7 @@ static int pgfuse_readdir( const char *path, void *buf, fuse_fill_dir_t filler,
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Readdir '%s' on '%s', thread #%u",
+ syslog( LOG_INFO, "Readdir '%s' on '%s', thread %p",
path, data->mountpoint, THREAD_ID );
}
@@ -606,7 +606,7 @@ static int pgfuse_mkdir( const char *path, mode_t mode )
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Mkdir '%s' in mode '%o' on '%s', thread #%u",
+ syslog( LOG_INFO, "Mkdir '%s' in mode '%o' on '%s', thread %p",
path, (unsigned int)mode, data->mountpoint,
THREAD_ID );
}
@@ -639,7 +639,7 @@ static int pgfuse_mkdir( const char *path, mode_t mode )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Parent_id for new dir '%s' is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Parent_id for new dir '%s' is %"PRIi64", thread %p",
path, parent_id, THREAD_ID );
}
@@ -685,7 +685,7 @@ static int pgfuse_rmdir( const char *path )
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Rmdir '%s' on '%s', thread #%u",
+ syslog( LOG_INFO, "Rmdir '%s' on '%s', thread %p",
path, data->mountpoint, THREAD_ID );
}
@@ -703,7 +703,7 @@ static int pgfuse_rmdir( const char *path )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id of dir '%s' to be removed is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Id of dir '%s' to be removed is %"PRIi64", thread %p",
path, id, THREAD_ID );
}
@@ -735,7 +735,7 @@ static int pgfuse_unlink( const char *path )
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Remove file '%s' on '%s', thread #%u",
+ syslog( LOG_INFO, "Remove file '%s' on '%s', thread %p",
path, data->mountpoint, THREAD_ID );
}
@@ -753,7 +753,7 @@ static int pgfuse_unlink( const char *path )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id of file '%s' to be removed is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Id of file '%s' to be removed is %"PRIi64", thread %p",
path, id, THREAD_ID );
}
@@ -788,7 +788,7 @@ static int pgfuse_fsync( const char *path, int isdatasync, struct fuse_file_info
PgFuseData *data = (PgFuseData *)fuse_get_context( )->private_data;
if( data->verbose ) {
- syslog( LOG_INFO, "%s on file '%s' on '%s', thread #%u",
+ syslog( LOG_INFO, "%s on file '%s' on '%s', thread %p",
isdatasync ? "FDataSync" : "FSync", path, data->mountpoint,
THREAD_ID );
}
@@ -815,7 +815,7 @@ static int pgfuse_release( const char *path, struct fuse_file_info *fi )
/* nothing to do given the simple transaction model */
if( data->verbose ) {
- syslog( LOG_INFO, "Releasing '%s' on '%s', thread #%u",
+ syslog( LOG_INFO, "Releasing '%s' on '%s', thread %p",
path, data->mountpoint, THREAD_ID );
}
@@ -858,7 +858,7 @@ static int pgfuse_write( const char *path, const char *buf, size_t size,
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Write to '%s' from offset %jd, size %zu on '%s', thread #%u",
+ syslog( LOG_INFO, "Write to '%s' from offset %jd, size %zu on '%s', thread %p",
path, offset, size, data->mountpoint,
THREAD_ID );
}
@@ -921,7 +921,7 @@ static int pgfuse_read( const char *path, char *buf, size_t size,
PgMeta meta;
if( data->verbose ) {
- syslog( LOG_INFO, "Read to '%s' from offset %jd, size %zu on '%s', thread #%u",
+ syslog( LOG_INFO, "Read to '%s' from offset %jd, size %zu on '%s', thread %p",
path, offset, size, data->mountpoint,
THREAD_ID );
}
@@ -971,7 +971,7 @@ static int pgfuse_truncate( const char* path, off_t offset )
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Truncate of '%s' to size '%jd' on '%s', thread #%u",
+ syslog( LOG_INFO, "Truncate of '%s' to size '%jd' on '%s', thread %p",
path, offset, data->mountpoint, THREAD_ID );
}
@@ -990,7 +990,7 @@ static int pgfuse_truncate( const char* path, off_t offset )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id of file '%s' to be truncated is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Id of file '%s' to be truncated is %"PRIi64", thread %p",
path, id, THREAD_ID );
}
@@ -1029,7 +1029,7 @@ static int pgfuse_ftruncate( const char *path, off_t offset, struct fuse_file_in
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Truncate of '%s' to size '%jd' on '%s', thread #%u",
+ syslog( LOG_INFO, "Truncate of '%s' to size '%jd' on '%s', thread %p",
path, offset, data->mountpoint,
THREAD_ID );
}
@@ -1092,7 +1092,7 @@ static int pgfuse_statfs( const char *path, struct statvfs *buf )
int prefix_len;
if( data->verbose ) {
- syslog( LOG_INFO, "Statfs called on '%s', thread #%u",
+ syslog( LOG_INFO, "Statfs called on '%s', thread %p",
data->mountpoint, THREAD_ID );
}
@@ -1115,7 +1115,7 @@ static int pgfuse_statfs( const char *path, struct statvfs *buf )
char *new_path = realpath( old_path, NULL );
if( new_path == NULL ) {
/* do nothing, most likely a permission problem */
- syslog( LOG_ERR, "realpath for '%s' failed: %s, pgfuse mount point '%s', thread #%u",
+ syslog( LOG_ERR, "realpath for '%s' failed: %s, pgfuse mount point '%s', thread %p",
old_path, strerror( errno ), data->mountpoint, THREAD_ID );
} else {
location[i] = new_path;
@@ -1152,13 +1152,13 @@ static int pgfuse_statfs( const char *path, struct statvfs *buf )
/* get data of file system */
res = statfs( prefix, &fs );
if( res < 0 ) {
- syslog( LOG_ERR, "statfs on '%s' failed: %s, pgfuse mount point '%s', thread #%u",
+ syslog( LOG_ERR, "statfs on '%s' failed: %s, pgfuse mount point '%s', thread %p",
prefix, strerror( errno ), data->mountpoint, THREAD_ID );
return res;
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Checking mount point '%s' for free disk space, now %jd, was %jd, pgfuse mount point '%s', thread #%u",
+ syslog( LOG_DEBUG, "Checking mount point '%s' for free disk space, now %jd, was %jd, pgfuse mount point '%s', thread %p",
prefix, fs.f_bfree, blocks_free, data->mountpoint, THREAD_ID );
}
@@ -1206,7 +1206,7 @@ static int pgfuse_statfs( const char *path, struct statvfs *buf )
if( data->verbose ) {
syslog( LOG_DEBUG, "Stats for '%s' are (%jd blocks total, %jd used, %jd free, "
- "%"PRId64" inodes total, %"PRId64" inodes used, %"PRId64" inodes free, thread #%u",
+ "%"PRId64" inodes total, %"PRId64" inodes used, %"PRId64" inodes free, thread %p",
data->mountpoint,
blocks_total, blocks_used, blocks_free,
files_total, files_used, files_free,
@@ -1245,7 +1245,7 @@ static int pgfuse_chmod( const char *path, mode_t mode )
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Chmod on '%s' to mode '%o' on '%s', thread #%u",
+ syslog( LOG_INFO, "Chmod on '%s' to mode '%o' on '%s', thread %p",
path, (unsigned int)mode, data->mountpoint,
THREAD_ID );
}
@@ -1287,7 +1287,7 @@ static int pgfuse_chown( const char *path, uid_t uid, gid_t gid )
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Chown on '%s' to uid '%d' and gid '%d' on '%s', thread #%u",
+ syslog( LOG_INFO, "Chown on '%s' to uid '%d' and gid '%d' on '%s', thread %p",
path, (unsigned int)uid, (unsigned int)gid, data->mountpoint,
THREAD_ID );
}
@@ -1334,7 +1334,7 @@ static int pgfuse_symlink( const char *from, const char *to )
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Symlink from '%s' to '%s' on '%s', thread #%u",
+ syslog( LOG_INFO, "Symlink from '%s' to '%s' on '%s', thread %p",
from, to, data->mountpoint, THREAD_ID );
}
@@ -1361,7 +1361,7 @@ static int pgfuse_symlink( const char *from, const char *to )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Parent_id for symlink '%s' is %"PRIi64", thread #%u",
+ syslog( LOG_DEBUG, "Parent_id for symlink '%s' is %"PRIi64", thread %p",
to, parent_id, THREAD_ID );
}
@@ -1446,7 +1446,7 @@ static int pgfuse_rename( const char *from, const char *to )
char *rename_to;
if( data->verbose ) {
- syslog( LOG_INFO, "Renaming '%s' to '%s' on '%s', thread #%u",
+ syslog( LOG_INFO, "Renaming '%s' to '%s' on '%s', thread %p",
from, to, data->mountpoint, THREAD_ID );
}
@@ -1553,7 +1553,7 @@ static int pgfuse_readlink( const char *path, char *buf, size_t size )
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Dereferencing symlink '%s' on '%s', thread #%u",
+ syslog( LOG_INFO, "Dereferencing symlink '%s' on '%s', thread %p",
path, data->mountpoint, THREAD_ID );
}
@@ -1597,7 +1597,7 @@ static int pgfuse_utimens( const char *path, const struct timespec tv[2] )
PGconn *conn;
if( data->verbose ) {
- syslog( LOG_INFO, "Utimens on '%s' to access time '%d' and modification time '%d' on '%s', thread #%u",
+ syslog( LOG_INFO, "Utimens on '%s' to access time '%d' and modification time '%d' on '%s', thread %p",
path, (unsigned int)tv[0].tv_sec, (unsigned int)tv[1].tv_sec, data->mountpoint,
THREAD_ID );
}
diff --git a/pool.c b/pool.c
index 11a0f1f..82b0644 100644
--- a/pool.c
+++ b/pool.c
@@ -22,8 +22,9 @@
#include <stdlib.h> /* for malloc */
#include <syslog.h> /* for syslog */
-#define AVAILABLE -1
-#define ERROR -2
+#define USED 1
+#define AVAILABLE 0
+#define ERROR 3
int psql_pool_init( PgConnPool *pool, const char *conninfo, const size_t max_connections )
{
@@ -35,16 +36,24 @@ int psql_pool_init( PgConnPool *pool, const char *conninfo, const size_t max_con
return -ENOMEM;
}
- pool->avail = (pthread_t *)malloc( sizeof( pthread_t ) * max_connections );
+ pool->avail = (unsigned int *)malloc( sizeof( unsigned int ) * max_connections );
if( pool->avail == NULL ) {
free( pool->conns );
return -ENOMEM;
}
+
+ pool->thread = (pthread_t *)malloc( sizeof( pthread_t ) * max_connections );
+ if( pool->thread == NULL ) {
+ free( pool->avail );
+ free( pool->conns );
+ return -ENOMEM;
+ }
pool->size = max_connections;
res = pthread_mutex_init( &pool->lock, NULL );
if( res < 0 ) {
+ free( pool->thread );
free( pool->avail );
free( pool->conns );
return res;
@@ -53,6 +62,7 @@ int psql_pool_init( PgConnPool *pool, const char *conninfo, const size_t max_con
res = pthread_cond_init( &pool->cond, NULL );
if( res < 0 ) {
(void)pthread_mutex_destroy( &pool->lock );
+ free( pool->thread );
free( pool->avail );
free( pool->conns );
return res;
@@ -80,17 +90,24 @@ int psql_pool_destroy( PgConnPool *pool )
int res2;
for( i = 0; i < pool->size; i++ ) {
- if( pool->avail[i] == AVAILABLE ) {
- PQfinish( pool->conns[i] );
- } else if( pool->avail[i] > 0 ) {
- syslog( LOG_ERR, "Destroying pool connection to thread '%u' which is still in use",
- (unsigned int)pool->avail[i] );
- PQfinish( pool->conns[i] );
+ switch( pool->avail[i] ) {
+ case AVAILABLE:
+ PQfinish( pool->conns[i] );
+ break;
+ case USED:
+ syslog( LOG_ERR, "Destroying pool connection to thread %p which is still in use",
+ pool->thread[i] );
+ PQfinish( pool->conns[i] );
+ break;
+ case ERROR:
+ // ignoring threads in error, asusming PQfinish will fail anyway
+ break;
}
}
free( pool->conns );
free( pool->avail );
+ free( pool->thread );
res1 = pthread_cond_destroy( &pool->cond );
res2 = pthread_mutex_destroy( &pool->lock );
@@ -106,8 +123,8 @@ PGconn *psql_pool_acquire( PgConnPool *pool )
for( ;; ) {
res = pthread_mutex_lock( &pool->lock );
if( res < 0 ) {
- syslog( LOG_ERR, "Locking mutex failed for thread '%u': %d",
- (unsigned int)pthread_self( ), res );
+ syslog( LOG_ERR, "Locking mutex failed for thread %p: %d",
+ pthread_self( ), res );
return NULL;
}
@@ -115,7 +132,8 @@ PGconn *psql_pool_acquire( PgConnPool *pool )
for( i = 0; i < pool->size; i++ ) {
if( pool->avail[i] == AVAILABLE ) {
if( PQstatus( pool->conns[i] ) == CONNECTION_OK ) {
- pool->avail[i] = pthread_self( );
+ pool->avail[i] = USED;
+ pool->thread[i] = pthread_self( );
(void)pthread_mutex_unlock( &pool->lock );
return pool->conns[i];
} else {
@@ -127,8 +145,8 @@ PGconn *psql_pool_acquire( PgConnPool *pool )
/* wait on conditional till a free connection is signalled */
res = pthread_cond_wait( &pool->cond, &pool->lock );
if( res < 0 ) {
- syslog( LOG_ERR, "Error waiting for free condition in thread '%u': %d",
- (unsigned int)pthread_self( ), res );
+ syslog( LOG_ERR, "Error waiting for free condition in thread %p: %d",
+ pthread_self( ), res );
(void)pthread_mutex_unlock( &pool->lock );
return NULL;
}
diff --git a/pool.h b/pool.h
index c8b5036..3dbc7f7 100644
--- a/pool.h
+++ b/pool.h
@@ -27,7 +27,8 @@
typedef struct PgConnPool {
PGconn **conns; /* array of connections */
size_t size; /* max number of connections */
- pthread_t *avail; /* slots of allocated/available connections per thread */
+ unsigned int *avail; /* status of slots */
+ pthread_t *thread; /* slots of allocated/available connections per thread */
pthread_mutex_t lock; /* monitor lock */
pthread_cond_t cond; /* condition signalling a free connection */
} PgConnPool;