diff --git a/configure.ac b/configure.ac index 96f0d6eb..8c17ad8e 100644 --- a/configure.ac +++ b/configure.ac @@ -85,7 +85,15 @@ AC_SEARCH_LIBS([pthread_setname_np], [pthread], [AC_MSG_RESULT([[no]])])], [AC_SEARCH_LIBS([pthread_set_name_np], [pthread], [AC_CHECK_FUNCS([pthread_set_name_np])])]) - +AC_SEARCH_LIBS([pthread_getname_np], [pthread], + [AC_DEFINE([HAVE_PTHREAD_GETNAME_NP], 1, + [Define to 1 if you have pthread_getname_np])] + [AC_SEARCH_LIBS([pthread_get_name_np], [pthread], + [AC_DEFINE([HAVE_PTHREAD_GETNAME_NP], 1, + [Define to 1 if you have pthread_get_name_np])])]) +AC_SEARCH_LIBS([pthread_getthreadid_np], [pthread], + [AC_DEFINE([HAVE_PTHREAD_GETTHREADID_NP], 1, + [Define to 1 if you have pthread_getthreadid_np])]) AC_SEARCH_LIBS([uuid_generate_random], [uuid], [AC_DEFINE([HAVE_UUID], 1, [Define to 1 if you have uuid_generate_random function])]) diff --git a/src/db.c b/src/db.c index 2b209b95..d98ebeb4 100644 --- a/src/db.c +++ b/src/db.c @@ -102,6 +102,7 @@ enum fixup_type { }; struct db_unlock { + char thread_name_tid[32]; int proceed; pthread_cond_t cond; pthread_mutex_t lck; @@ -1446,6 +1447,7 @@ unlock_notify_cb(void **args, int nargs) { u = (struct db_unlock *)args[i]; + DPRINTF(E_DBG, L_DB, "Notify DB unlock, thread: %s\n", u->thread_name_tid); CHECK_ERR(L_DB, pthread_mutex_lock(&u->lck)); u->proceed = 1; @@ -1461,6 +1463,8 @@ db_wait_unlock(void) struct db_unlock u; int ret; + thread_getnametid(u.thread_name_tid, sizeof(u.thread_name_tid)); + u.proceed = 0; CHECK_ERR(L_DB, mutex_init(&u.lck)); CHECK_ERR(L_DB, pthread_cond_init(&u.cond, NULL)); @@ -1477,7 +1481,7 @@ db_wait_unlock(void) } CHECK_ERR(L_DB, pthread_mutex_unlock(&u.lck)); - } +} CHECK_ERR(L_DB, pthread_cond_destroy(&u.cond)); CHECK_ERR(L_DB, pthread_mutex_destroy(&u.lck)); diff --git a/src/httpd.c b/src/httpd.c index 2d8c04b6..81ac7ef7 100644 --- a/src/httpd.c +++ b/src/httpd.c @@ -985,9 +985,7 @@ request_async_cb(void *arg) { struct httpd_request *hreq = *(struct httpd_request **)arg; -#ifdef HAVE_GETTID - DPRINTF(E_DBG, hreq->module->logdomain, "%s request '%s' in worker thread %d\n", hreq->module->name, hreq->uri, (int)gettid()); -#endif + DPRINTF(E_DBG, hreq->module->logdomain, "%s request '%s'\n", hreq->module->name, hreq->uri); // Some handlers require an evbase to schedule events hreq->evbase = worker_evbase_get(); diff --git a/src/httpd_jsonapi.c b/src/httpd_jsonapi.c index 5e39474e..7beba57c 100644 --- a/src/httpd_jsonapi.c +++ b/src/httpd_jsonapi.c @@ -2623,6 +2623,7 @@ static int jsonapi_reply_queue_tracks_delete(struct httpd_request *hreq) { uint32_t item_id; + uint32_t count; int ret; ret = safe_atou32(hreq->path_parts[3], &item_id); @@ -2639,6 +2640,13 @@ jsonapi_reply_queue_tracks_delete(struct httpd_request *hreq) return HTTP_INTERNAL; } + db_queue_get_count(&count); + if (count == 0) + { + player_playback_stop(); + db_queue_clear(0); + } + return HTTP_NOCONTENT; } diff --git a/src/logger.c b/src/logger.c index 0429fafe..43dc0ba2 100644 --- a/src/logger.c +++ b/src/logger.c @@ -136,16 +136,19 @@ static void logger_write_with_label(int severity, int domain, const char *content) { char stamp[32]; + char thread_nametid[32]; time_t t; struct tm timebuf; int ret; + thread_getnametid(thread_nametid, sizeof(thread_nametid)); + t = time(NULL); ret = strftime(stamp, sizeof(stamp), "%Y-%m-%d %H:%M:%S", localtime_r(&t, &timebuf)); if (ret == 0) stamp[0] = '\0'; - logger_write("[%s] [%5s] %8s: %s", stamp, severities[severity], labels[domain], content); + logger_write("[%s] [%5s] [%16s] %8s: %s", stamp, severities[severity], thread_nametid, labels[domain], content); } static void diff --git a/src/misc.c b/src/misc.c index aeb17f84..8f84eb84 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1788,6 +1788,42 @@ mutex_init(pthread_mutex_t *mutex) return err; } +int +thread_gettid() +{ + int tid = -1; +#if defined(HAVE_GETTID) + tid = (int)gettid(); +#elif defined(HAVE_PTHREAD_GETTHREADID_NP) + tid = pthread_getthreadid_np(); +#endif + return tid; +} + +void +thread_getname(pthread_t thread, char *name, size_t len) +{ +#if defined(HAVE_PTHREAD_GETNAME_NP) + pthread_getname_np(thread, name, len); +#elif defined(HAVE_PTHREAD_GET_NAME_NP) + pthread_get_name_np(thread, name, len); +#else + name[0] = '\0'; +#endif +} + +void +thread_getnametid(char *buf, size_t len) +{ + int tid; + char thread_name[32]; + pthread_t p = pthread_self(); + + thread_getname(p, thread_name, sizeof(thread_name)); + tid = thread_gettid() % 10000; + snprintf(buf, len, "%s (%d)", thread_name, tid); +} + void thread_setname(pthread_t thread, const char *name) { diff --git a/src/misc.h b/src/misc.h index fe5615a5..7ac16b19 100644 --- a/src/misc.h +++ b/src/misc.h @@ -316,6 +316,17 @@ buildopts_get(void); int mutex_init(pthread_mutex_t *mutex); +// wrapper for gettid/pthread_getthreadid_np +int +thread_gettid(); + +// wrapper for pthread_getname_np/pthread_get_name_np +void +thread_getname(pthread_t thread, char *name, size_t len); + +void +thread_getnametid(char *buf, size_t len); + // wrapper for pthread_setname_np/pthread_set_name_np void thread_setname(pthread_t thread, const char *name); diff --git a/src/outputs/airplay.c b/src/outputs/airplay.c index c18b4625..bc2bacde 100644 --- a/src/outputs/airplay.c +++ b/src/outputs/airplay.c @@ -2084,7 +2084,7 @@ packets_sync_send(struct airplay_master_session *rms) control_packet_send(rs, sync_pkt); DPRINTF(E_DBG, L_AIRPLAY, "Start sync packet sent to '%s': cur_pos=%" PRIu32 ", cur_ts=%ld.%09ld, clock=%ld.%09ld, rtptime=%" PRIu32 "\n", - rs->devname, rms->cur_stamp.pos, rms->cur_stamp.ts.tv_sec, rms->cur_stamp.ts.tv_nsec, ts.tv_sec, ts.tv_nsec, rms->rtp_session->pos); + rs->devname, rms->cur_stamp.pos, (long)rms->cur_stamp.ts.tv_sec, (long)rms->cur_stamp.ts.tv_nsec, (long)ts.tv_sec, (long)ts.tv_nsec, rms->rtp_session->pos); } else if (is_sync_time && rs->state == AIRPLAY_STATE_STREAMING) { diff --git a/src/outputs/alsa.c b/src/outputs/alsa.c index 37fdb902..c90bc28a 100644 --- a/src/outputs/alsa.c +++ b/src/outputs/alsa.c @@ -900,8 +900,8 @@ sync_check(double *drift, double *latency, struct alsa_playback_session *pb, snd exp_pos = (uint64_t)elapsed * pb->quality.sample_rate / 1000; diff = cur_pos - exp_pos; - DPRINTF(E_SPAM, L_LAUDIO, "counter %d/%d, stamp %lu:%lu, now %lu:%lu, elapsed is %d ms, cur_pos=%" PRIu64 ", exp_pos=%" PRIu64 ", diff=%d\n", - pb->latency_counter, alsa_latency_history_size, pb->stamp_pts.tv_sec, pb->stamp_pts.tv_nsec / 1000000, ts.tv_sec, ts.tv_nsec / 1000000, elapsed, cur_pos, exp_pos, diff); + DPRINTF(E_SPAM, L_LAUDIO, "counter %d/%d, stamp %ld:%09ld, now %ld:%09ld, elapsed is %d ms, cur_pos=%" PRIu64 ", exp_pos=%" PRIu64 ", diff=%d\n", + pb->latency_counter, alsa_latency_history_size, (long)pb->stamp_pts.tv_sec, (long)pb->stamp_pts.tv_nsec, (long)ts.tv_sec, (long)ts.tv_nsec, elapsed, cur_pos, exp_pos, diff); // Add the latency to our measurement history pb->latency_history[pb->latency_counter] = (double)diff; diff --git a/src/outputs/cast.c b/src/outputs/cast.c index 80cc1494..775a4a9f 100644 --- a/src/outputs/cast.c +++ b/src/outputs/cast.c @@ -1953,7 +1953,7 @@ cast_session_make(struct output_device *device, int family, int callback_id) cs->offset_ts.tv_sec = (offset_ms / 1000); cs->offset_ts.tv_nsec = (offset_ms % 1000) * 1000000UL; - DPRINTF(E_DBG, L_CAST, "Offset is set to %lu:%09lu\n", cs->offset_ts.tv_sec, cs->offset_ts.tv_nsec); + DPRINTF(E_DBG, L_CAST, "Offset is set to %ld:%09ld\n", (long)cs->offset_ts.tv_sec, (long)cs->offset_ts.tv_nsec); cs->ev = event_new(evbase_player, cs->server_fd, EV_READ | EV_PERSIST, cast_listen_cb, cs); if (!cs->ev) @@ -2254,7 +2254,7 @@ cast_write(struct output_buffer *obuf) cs->state = CAST_STATE_BUFFERING; clock_gettime(CLOCK_MONOTONIC, &ts); - DPRINTF(E_DBG, L_CAST, "Start time is %lu:%lu, current time is %lu:%lu\n", cs->start_pts.tv_sec, cs->start_pts.tv_nsec, ts.tv_sec, ts.tv_nsec); + DPRINTF(E_DBG, L_CAST, "Start time is %ld:%09ld,, current time is %ld:%09ld,\n", (long)cs->start_pts.tv_sec, (long)cs->start_pts.tv_nsec, (long)ts.tv_sec, (long)ts.tv_nsec); } if (cs->state == CAST_STATE_BUFFERING) diff --git a/src/outputs/raop.c b/src/outputs/raop.c index f37a6b7d..a4b8f310 100644 --- a/src/outputs/raop.c +++ b/src/outputs/raop.c @@ -3043,7 +3043,7 @@ packets_sync_send(struct raop_master_session *rms) control_packet_send(rs, sync_pkt); DPRINTF(E_DBG, L_RAOP, "Start sync packet sent to '%s': cur_pos=%" PRIu32 ", cur_ts=%ld.%09ld, clock=%ld.%09ld, rtptime=%" PRIu32 "\n", - rs->devname, rms->cur_stamp.pos, rms->cur_stamp.ts.tv_sec, rms->cur_stamp.ts.tv_nsec, ts.tv_sec, ts.tv_nsec, rms->rtp_session->pos); + rs->devname, rms->cur_stamp.pos, (long)rms->cur_stamp.ts.tv_sec, (long)rms->cur_stamp.ts.tv_nsec, (long)ts.tv_sec, (long)ts.tv_nsec, rms->rtp_session->pos); } else if (is_sync_time && rs->state == RAOP_STATE_STREAMING) { diff --git a/src/outputs/rcp.c b/src/outputs/rcp.c index 0c0bbf7f..348ffa0d 100644 --- a/src/outputs/rcp.c +++ b/src/outputs/rcp.c @@ -861,7 +861,7 @@ rcp_session_shutdown_init(struct rcp_session* s) } else { - DPRINTF(E_DBG, L_RCP, "Limiting shutdown timeout %ld sec '%s' at %s\n", clear_timeout.tv_sec, s->devname, s->address); + DPRINTF(E_DBG, L_RCP, "Limiting shutdown timeout %ld sec '%s' at %s\n", (long)clear_timeout.tv_sec, s->devname, s->address); // ensure we're not blocked forever on responses event_add(s->reply_timeout, &clear_timeout);