| 1866 | } |
| 1867 | |
| 1868 | static bool application_update_reap(cbm_daemon_application_t *application, bool wait, |
| 1869 | uint32_t timeout_ms) { |
| 1870 | if (!application) { |
| 1871 | return false; |
| 1872 | } |
| 1873 | uint64_t deadline = application_deadline_after(timeout_ms); |
| 1874 | for (;;) { |
| 1875 | bool join = false; |
| 1876 | cbm_mutex_lock(&application->mutex); |
| 1877 | if (!application->update_thread_started) { |
| 1878 | cbm_mutex_unlock(&application->mutex); |
| 1879 | return true; |
| 1880 | } |
| 1881 | if (application->update_thread_done && !application->update_thread_joining) { |
| 1882 | application->update_thread_joining = true; |
| 1883 | join = true; |
| 1884 | } |
| 1885 | cbm_mutex_unlock(&application->mutex); |
| 1886 | if (join) { |
| 1887 | bool joined = cbm_thread_join(&application->update_thread) == 0; |
| 1888 | cbm_mutex_lock(&application->mutex); |
| 1889 | if (joined) { |
| 1890 | application->update_thread_started = false; |
| 1891 | } |
| 1892 | application->update_thread_joining = false; |
| 1893 | cbm_mutex_unlock(&application->mutex); |
| 1894 | return joined; |
| 1895 | } |
| 1896 | if (!wait || cbm_now_ms() >= deadline) { |
| 1897 | return false; |
| 1898 | } |
| 1899 | cbm_usleep(APPLICATION_UPDATE_POLL_US); |
| 1900 | } |
| 1901 | } |
| 1902 | |
| 1903 | static char *application_auto_index_args(const char *root_path) { |
| 1904 | yyjson_mut_doc *document = yyjson_mut_doc_new(NULL); |
no test coverage detected