Files
mergerfs/vendored/libfuse/lib/maintenance_thread.cpp
Antonio S. Musumeci ec40866091 libfuse: small safety and portability fixes across opt/cpu/fusermount/maintenance_thread
- fuse_opt: reformat process_opt_param to project style; return the
  rv from sscanf through a named local so the error branch prints
  the failing option cleanly.

- cpu.cpp: when parsing /sys/devices/system/cpu/*/topology/core_id,
  bail out cleanly on stream read failure rather than recording an
  uninitialized core_id.

- fusermount: free(copy) on the success path of parsing the mount
  option (previously leaked on every mount), and replace the fixed-
  buffer sprintf into procfile with snprintf bounded by the buffer
  size.

- maintenance_thread: widen the iteration count from int to u64
  so a long-lived daemon doesn't wrap after ~68 years of ticks
  (real effect: silence signed-overflow warnings under UBSan).
2026-04-18 13:47:23 -05:00

65 lines
1.0 KiB
C++

#include "maintenance_thread.hpp"
#include "fatal.hpp"
#include "mutex.hpp"
#include <vector>
#include <pthread.h>
#include <unistd.h>
static pthread_t g_thread;
static std::vector<std::function<void(u64)>> g_funcs;
static mutex_t g_mutex;
static
void*
_thread_loop(void *)
{
u64 count;
pthread_setname_np(pthread_self(),"fuse.maint");
count = 0;
while(true)
{
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
{
LockGuard lg(g_mutex);
for(auto &func : g_funcs)
func(count);
}
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
count++;
::sleep(60);
}
return NULL;
}
void
MaintenanceThread::setup()
{
int rv;
rv = pthread_create(&g_thread,NULL,_thread_loop,NULL);
if(rv != 0)
fatal::abort("pthread_create failed: rv={}",rv);
}
void
MaintenanceThread::push_job(const std::function<void(u64)> &func_)
{
LockGuard lg(g_mutex);
g_funcs.emplace_back(func_);
}
void
MaintenanceThread::stop()
{
pthread_cancel(g_thread);
pthread_join(g_thread,NULL);
}