| 2932 | } |
| 2933 | |
| 2934 | bool cbm_daemon_application_shutdown(cbm_daemon_application_t *application, uint32_t timeout_ms) { |
| 2935 | if (!application) { |
| 2936 | return false; |
| 2937 | } |
| 2938 | uint64_t deadline = application_deadline_after(timeout_ms); |
| 2939 | cbm_mutex_lock(&application->mutex); |
| 2940 | application->stopping = true; |
| 2941 | for (cbm_daemon_application_session_t *session = application->sessions; session; |
| 2942 | session = session->next) { |
| 2943 | (void)cbm_mcp_server_cancel_active(session->mcp); |
| 2944 | if (session->auto_index_job && session->auto_index_subscribed) { |
| 2945 | application_job_unsubscribe_locked(session->auto_index_job); |
| 2946 | session->auto_index_job = NULL; |
| 2947 | session->auto_index_subscribed = false; |
| 2948 | } |
| 2949 | (void)application_update_owner_release_locked(session); |
| 2950 | } |
| 2951 | application_cancel_jobs_locked(application); |
| 2952 | application_update_cancel_locked(application); |
| 2953 | cbm_mutex_unlock(&application->mutex); |
| 2954 | for (;;) { |
| 2955 | bool all_done = true; |
| 2956 | cbm_mutex_lock(&application->mutex); |
| 2957 | if (application->active_mutations != 0) { |
| 2958 | all_done = false; |
| 2959 | } |
| 2960 | if (application->update_thread_started && !application->update_thread_done) { |
| 2961 | all_done = false; |
| 2962 | } |
| 2963 | for (cbm_daemon_application_session_t *session = application->sessions; all_done && session; |
| 2964 | session = session->next) { |
| 2965 | if (session->request_active) { |
| 2966 | all_done = false; |
| 2967 | } |
| 2968 | } |
| 2969 | for (cbm_daemon_application_job_t *job = application->jobs; job; job = job->next) { |
| 2970 | if (!job->thread_done || job->subscribers != 0 || job->watcher_waiters != 0) { |
| 2971 | all_done = false; |
| 2972 | break; |
| 2973 | } |
| 2974 | } |
| 2975 | cbm_mutex_unlock(&application->mutex); |
| 2976 | if (all_done) { |
| 2977 | application_jobs_reap_completed(application); |
| 2978 | uint64_t now = cbm_now_ms(); |
| 2979 | uint32_t remaining = |
| 2980 | now >= deadline |
| 2981 | ? 0 |
| 2982 | : (uint32_t)((deadline - now) > UINT32_MAX ? UINT32_MAX : deadline - now); |
| 2983 | return application_update_reap(application, true, remaining); |
| 2984 | } |
| 2985 | if (cbm_now_ms() >= deadline) { |
| 2986 | return false; |
| 2987 | } |
| 2988 | cbm_usleep(APPLICATION_JOB_POLL_US); |
| 2989 | } |
| 2990 | } |
| 2991 | |