Skip to content

Commit

Permalink
Merge pull request #17961 from jenshannoschwalm/two_regressions
Browse files Browse the repository at this point in the history
Fixing three regressions / bugs
  • Loading branch information
TurboGit authored Dec 8, 2024
2 parents 7c8ca81 + cfeba7c commit b126153
Show file tree
Hide file tree
Showing 12 changed files with 215 additions and 74 deletions.
1 change: 1 addition & 0 deletions src/common/cups_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ static int _detect_printers_callback(dt_job_t *job)
res=1;
}
#endif
darktable.control->cups_started = TRUE;
return !res;
}

Expand Down
11 changes: 8 additions & 3 deletions src/common/darktable.c
Original file line number Diff line number Diff line change
Expand Up @@ -1590,8 +1590,7 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load
if(dbfilename_from_command && !strcmp(dbfilename_from_command, ":memory:"))
dt_gui_presets_init(); // init preset db schema.

darktable.control->running = FALSE;
dt_pthread_mutex_init(&darktable.control->run_mutex, NULL);
g_atomic_int_set(&darktable.control->running, DT_CONTROL_STATE_DISABLED);
dt_pthread_mutex_init(&darktable.control->log_mutex, NULL);
}

Expand Down Expand Up @@ -2011,7 +2010,13 @@ void dt_cleanup()
// if(init_gui)
// darktable_exit_screen_create(NULL, FALSE);

darktable.backthumbs.running = FALSE;
if(darktable.backthumbs.running)
{
// if the backthumbs crawler is running, stop it now and wait for it being terminated.
darktable.backthumbs.running = FALSE;
for(int i = 0; i < 1000 && darktable.backthumbs.capable; i++)
g_usleep(10000);
}
// last chance to ask user for any input...

const gboolean perform_maintenance = dt_database_maybe_maintenance(darktable.db);
Expand Down
10 changes: 8 additions & 2 deletions src/common/dtpthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

int dt_pthread_create(pthread_t *thread, void *(*start_routine)(void *), void *arg)
{
int ret;
int ret = 0;

pthread_attr_t attr;

Expand Down Expand Up @@ -63,7 +63,13 @@ int dt_pthread_create(pthread_t *thread, void *(*start_routine)(void *), void *a
}
}

ret = pthread_create(thread, &attr, start_routine, arg);
if(ret == 0)
ret = pthread_create(thread, &attr, start_routine, arg);

if(ret != 0)
{
fprintf(stderr, "[dt_pthread_create] error: pthread_create() returned %i\n", ret);
}

pthread_attr_destroy(&attr);

Expand Down
128 changes: 108 additions & 20 deletions src/common/dtpthread.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
This file is part of darktable,
Copyright (C) 2010-2020 darktable developers.
Copyright (C) 2010-2024 darktable developers.
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -28,8 +28,35 @@
#include <stdlib.h>
#include <string.h>

// #define MUTEX_REPORTING // uncomment to include runtime report of mutex problems also for release builds

static inline const char *_pthread_ret_mess(int error)
{
switch(error)
{
case 0: return "OK";
case EBUSY: return "EBUSY";
case EINVAL: return "EINVAL";
case EAGAIN: return "EAGAIN";
case EDEADLK: return "EDEADLK";
case EPERM: return "EPERM";
case ETIMEDOUT: return "ETIMEDOUT";
case ESRCH: return "ESRCH";
default: return "???";
}
}

static inline void _ret_error(const int ret, const char* mess)
{
fprintf(stderr, "\n*** [dt_pthread_mutex_%s = %s] ***\n", mess ? mess : "???", _pthread_ret_mess(ret));
}

#ifdef _DEBUG

#ifndef MUTEX_REPORTING
#define MUTEX_REPORTING // make sure we report the BAD variants
#endif

// copied from darktable.h so we don't need to include the header
#include <sys/time.h>
static inline double dt_pthread_get_wtime()
Expand All @@ -39,7 +66,6 @@ static inline double dt_pthread_get_wtime()
return time.tv_sec - 1290608000 + (1.0 / 1000000.0) * time.tv_usec;
}


#define TOPN 3
typedef struct CAPABILITY("mutex") dt_pthread_mutex_t
{
Expand All @@ -62,10 +88,17 @@ typedef struct dt_pthread_rwlock_t
char name[256];
} dt_pthread_rwlock_t;

static inline void _report_ret_error(const int ret, const char* loc, const char* mess)
{
fprintf(stderr, "[dt_pthread_mutex_%s = %s] at: %s\n",
mess ? mess : "???", _pthread_ret_mess(ret), loc ? loc : "no location");
}

static inline int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
{
const int ret = pthread_mutex_destroy(&(mutex->mutex));
assert(!ret);
if(ret) _report_ret_error(ret, mutex->name, "destroy");
assert(ret == 0);

#if 0
printf("\n[mutex] stats for mutex `%s':\n", mutex->name);
Expand All @@ -78,7 +111,6 @@ static inline int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
for(int k=0; k<TOPN; k++) printf("[mutex] %.3f secs : `%s'\n", mutex->top_wait_sum[k],
mutex->top_wait_name[k]);
#endif

return ret;
}

Expand All @@ -100,9 +132,7 @@ static inline int dt_pthread_mutex_init_with_caller(dt_pthread_mutex_t *mutex,
return ret;
}
#endif
const int ret = pthread_mutex_init(&(mutex->mutex), attr);
assert(!ret);
return ret;
return pthread_mutex_init(&(mutex->mutex), attr);
}

#define dt_pthread_mutex_lock(A) dt_pthread_mutex_lock_with_caller(A, __FILE__, __LINE__, __FUNCTION__)
Expand All @@ -112,6 +142,7 @@ static inline int dt_pthread_mutex_lock_with_caller(dt_pthread_mutex_t *mutex, c
{
const double t0 = dt_pthread_get_wtime();
const int ret = pthread_mutex_lock(&(mutex->mutex));
if(ret) _report_ret_error(ret, mutex->name, "lock");
assert(!ret);
mutex->time_locked = dt_pthread_get_wtime();
double wait = mutex->time_locked - t0;
Expand Down Expand Up @@ -140,8 +171,9 @@ static inline int dt_pthread_mutex_trylock_with_caller(dt_pthread_mutex_t *mutex
{
const double t0 = dt_pthread_get_wtime();
const int ret = pthread_mutex_trylock(&(mutex->mutex));
if(ret && (ret != EBUSY)) _report_ret_error(ret, mutex->name, "trylock");
assert(!ret || (ret == EBUSY));
if(ret) return ret;

mutex->time_locked = dt_pthread_get_wtime();
double wait = mutex->time_locked - t0;
mutex->time_sum_wait += wait;
Expand Down Expand Up @@ -192,13 +224,17 @@ static inline int dt_pthread_mutex_unlock_with_caller(dt_pthread_mutex_t *mutex,

// need to unlock last, to shield our internal data.
const int ret = pthread_mutex_unlock(&(mutex->mutex));
if(ret) _report_ret_error(ret, mutex->name, "unlock");
assert(!ret);
return ret;
}

static inline int dt_pthread_cond_wait(pthread_cond_t *cond, dt_pthread_mutex_t *mutex)
{
return pthread_cond_wait(cond, &(mutex->mutex));
const int ret = pthread_cond_wait(cond, &(mutex->mutex));
if(ret) _report_ret_error(ret, mutex->name, "cond_wait");
assert(!ret);
return ret;
}


Expand Down Expand Up @@ -250,6 +286,7 @@ static inline int dt_pthread_rwlock_rdlock_with_caller(dt_pthread_rwlock_t *rwlo
snprintf(rwlock->name, sizeof(rwlock->name), "r:%s:%d", file, line);
return res;
}

#define dt_pthread_rwlock_wrlock(A) dt_pthread_rwlock_wrlock_with_caller(A, __FILE__, __LINE__)
static inline int dt_pthread_rwlock_wrlock_with_caller(dt_pthread_rwlock_t *rwlock, const char *file, int line)
{
Expand All @@ -263,6 +300,7 @@ static inline int dt_pthread_rwlock_wrlock_with_caller(dt_pthread_rwlock_t *rwlo
}
return res;
}

#define dt_pthread_rwlock_tryrdlock(A) dt_pthread_rwlock_tryrdlock_with_caller(A, __FILE__, __LINE__)
static inline int dt_pthread_rwlock_tryrdlock_with_caller(dt_pthread_rwlock_t *rwlock, const char *file, int line)
{
Expand All @@ -276,6 +314,7 @@ static inline int dt_pthread_rwlock_tryrdlock_with_caller(dt_pthread_rwlock_t *r
}
return res;
}

#define dt_pthread_rwlock_trywrlock(A) dt_pthread_rwlock_trywrlock_with_caller(A, __FILE__, __LINE__)
static inline int dt_pthread_rwlock_trywrlock_with_caller(dt_pthread_rwlock_t *rwlock, const char *file, int line)
{
Expand All @@ -291,7 +330,8 @@ static inline int dt_pthread_rwlock_trywrlock_with_caller(dt_pthread_rwlock_t *r
}

#undef TOPN
#else

#else /* Release builds */

typedef struct CAPABILITY("mutex") dt_pthread_mutex_t
{
Expand All @@ -302,32 +342,60 @@ typedef struct CAPABILITY("mutex") dt_pthread_mutex_t
static inline int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
{
return pthread_mutex_init(&mutex->mutex, mutexattr);
};
}

static inline int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
{
#ifdef MUTEX_REPORTING
const int ret = pthread_mutex_lock(&mutex->mutex);
if(ret) _ret_error(ret, "lock");
return ret;
#else
return pthread_mutex_lock(&mutex->mutex);
};
#endif
}

static inline int dt_pthread_mutex_trylock(dt_pthread_mutex_t *mutex) TRY_ACQUIRE(0, mutex)
{
#ifdef MUTEX_REPORTING
const int ret = pthread_mutex_trylock(&mutex->mutex);
if(ret && (ret != EBUSY)) _ret_error(ret, "trylock");
return ret;
#else
return pthread_mutex_trylock(&mutex->mutex);
};
#endif
}

static inline int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
{
#ifdef MUTEX_REPORTING
const int ret = pthread_mutex_unlock(&mutex->mutex);
if(ret) _ret_error(ret, "unlock");
return ret;
#else
return pthread_mutex_unlock(&mutex->mutex);
};
#endif
}

static inline int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
{
return pthread_mutex_destroy(&mutex->mutex);
};
int ret = pthread_mutex_destroy(&(mutex->mutex));
#ifdef MUTEX_REPORTING
if(ret) _ret_error(ret, "destroy");
#endif
return ret;
}

static inline int dt_pthread_cond_wait(pthread_cond_t *cond, dt_pthread_mutex_t *mutex)
{
#ifdef MUTEX_REPORTING
const int ret = pthread_cond_wait(cond, &mutex->mutex);
if(ret) _ret_error(ret, "cond_wait");
return ret;
#else
return pthread_cond_wait(cond, &mutex->mutex);
};
#endif
}

#define dt_pthread_rwlock_t pthread_rwlock_t
#define dt_pthread_rwlock_init pthread_rwlock_init
Expand All @@ -345,21 +413,41 @@ static inline int dt_pthread_cond_wait(pthread_cond_t *cond, dt_pthread_mutex_t

#endif

/* shared for _DEBUG and release builds */

// if at all possible, do NOT use.
static inline int dt_pthread_mutex_BAD_lock(dt_pthread_mutex_t *mutex)
{
#ifdef MUTEX_REPORTING
const int ret = pthread_mutex_lock(&mutex->mutex);
if(ret) _ret_error(ret, "BAD_lock");
return ret;
#else
return pthread_mutex_lock(&mutex->mutex);
};
#endif
}

static inline int dt_pthread_mutex_BAD_trylock(dt_pthread_mutex_t *mutex)
{
#ifdef MUTEX_REPORTING
const int ret = pthread_mutex_trylock(&mutex->mutex);
if(ret && (ret != EBUSY)) _ret_error(ret, "BAD_trylock");
return ret;
#else
return pthread_mutex_trylock(&mutex->mutex);
};
#endif
}

static inline int dt_pthread_mutex_BAD_unlock(dt_pthread_mutex_t *mutex)
{
#ifdef MUTEX_REPORTING
const int ret = pthread_mutex_unlock(&mutex->mutex);
if(ret) _ret_error(ret, "BAD_unlock");
return ret;
#else
return pthread_mutex_unlock(&mutex->mutex);
};
#endif
}

int dt_pthread_create(pthread_t *thread, void *(*start_routine)(void *), void *arg);

Expand Down
8 changes: 4 additions & 4 deletions src/common/opencl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,7 +1666,7 @@ gboolean dt_opencl_finish(const int devid)
// summary statistics
cl_int success = dt_opencl_events_flush(devid, FALSE);

return (err == CL_SUCCESS && success == CL_COMPLETE);
return (err == CL_SUCCESS && success == CL_SUCCESS);
}

gboolean dt_opencl_finish_sync_pipe(const int devid,
Expand Down Expand Up @@ -4028,8 +4028,8 @@ cl_int dt_opencl_events_flush(const int devid,
const gboolean reset)
{
dt_opencl_t *cl = darktable.opencl;
if(!cl->inited || devid < 0) return DT_OPENCL_NODEVICE;
if(!cl->dev[devid].use_events) return DT_OPENCL_NODEVICE;
if(!cl->inited || devid < 0) return CL_SUCCESS;
if(!cl->dev[devid].use_events) return CL_SUCCESS;

cl_event **eventlist = &(cl->dev[devid].eventlist);
dt_opencl_eventtag_t **eventtags = &(cl->dev[devid].eventtags);
Expand All @@ -4041,7 +4041,7 @@ cl_int dt_opencl_events_flush(const int devid,
cl_int *summary = &(cl->dev[devid].summary);

if(*eventlist == NULL || *numevents == 0)
return CL_COMPLETE; // nothing to do, no news is good news
return CL_SUCCESS; // nothing to do, no news is good news

// Wait for command queue to terminate (side effect: might adjust *numevents)
_opencl_events_wait_for(devid);
Expand Down
Loading

0 comments on commit b126153

Please sign in to comment.