1616#include "fsmonitor--daemon.h"
1717
1818#include "simple-ipc.h"
19- #include "strmap .h"
19+ #include "khash .h"
2020#include "run-command.h"
2121#include "trace.h"
2222#include "trace2.h"
@@ -86,8 +86,6 @@ static int do_as_client__send_stop(void)
8686{
8787 struct strbuf answer = STRBUF_INIT ;
8888 int ret ;
89- int max_wait_ms = 30000 ;
90- int elapsed_ms = 0 ;
9189
9290 ret = fsmonitor_ipc__send_command ("quit" , & answer );
9391
@@ -98,16 +96,8 @@ static int do_as_client__send_stop(void)
9896 return ret ;
9997
10098 trace2_region_enter ("fsm_client" , "polling-for-daemon-exit" , NULL );
101- while (fsmonitor_ipc__get_state () == IPC_STATE__LISTENING ) {
102- if (elapsed_ms >= max_wait_ms ) {
103- trace2_region_leave ("fsm_client" ,
104- "polling-for-daemon-exit" , NULL );
105- return error (_ ("daemon did not stop within %d seconds" ),
106- max_wait_ms / 1000 );
107- }
99+ while (fsmonitor_ipc__get_state () == IPC_STATE__LISTENING )
108100 sleep_millisec (50 );
109- elapsed_ms += 50 ;
110- }
111101 trace2_region_leave ("fsm_client" , "polling-for-daemon-exit" , NULL );
112102
113103 return 0 ;
@@ -207,31 +197,20 @@ static enum fsmonitor_cookie_item_result with_lock__wait_for_cookie(
207197 unlink (cookie_pathname .buf );
208198
209199 /*
210- * Wait for the listener thread to observe the cookie file.
211- * Time out after a short interval so that the client
212- * does not hang forever if the filesystem does not deliver
213- * events (e.g., on certain container/overlay filesystems
214- * where inotify watches succeed but events never arrive).
200+ * Technically, this is an infinite wait (well, unless another
201+ * thread sends us an abort). I'd like to change this to
202+ * use `pthread_cond_timedwait()` and return an error/timeout
203+ * and let the caller do the trivial response thing, but we
204+ * don't have that routine in our thread-utils.
205+ *
206+ * After extensive beta testing I'm not really worried about
207+ * this. Also note that the above open() and unlink() calls
208+ * will cause at least two FS events on that path, so the odds
209+ * of getting stuck are pretty slim.
215210 */
216- {
217- struct timeval now ;
218- struct timespec ts ;
219- int err = 0 ;
220-
221- gettimeofday (& now , NULL );
222- ts .tv_sec = now .tv_sec + 1 ;
223- ts .tv_nsec = now .tv_usec * 1000 ;
224-
225- while (cookie -> result == FCIR_INIT && !err )
226- err = pthread_cond_timedwait (& state -> cookies_cond ,
227- & state -> main_lock ,
228- & ts );
229- if (err == ETIMEDOUT && cookie -> result == FCIR_INIT ) {
230- trace_printf_key (& trace_fsmonitor ,
231- "cookie_wait timed out" );
232- cookie -> result = FCIR_ERROR ;
233- }
234- }
211+ while (cookie -> result == FCIR_INIT )
212+ pthread_cond_wait (& state -> cookies_cond ,
213+ & state -> main_lock );
235214
236215done :
237216 hashmap_remove (& state -> cookies , & cookie -> entry , NULL );
@@ -674,6 +653,8 @@ static int fsmonitor_parse_client_token(const char *buf_token,
674653 return 0 ;
675654}
676655
656+ KHASH_INIT (str , const char * , int , 0 , kh_str_hash_func , kh_str_hash_equal )
657+
677658static int do_handle_client (struct fsmonitor_daemon_state * state ,
678659 const char * command ,
679660 ipc_server_reply_cb * reply ,
@@ -690,7 +671,8 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,
690671 const struct fsmonitor_batch * batch ;
691672 struct fsmonitor_batch * remainder = NULL ;
692673 intmax_t count = 0 , duplicates = 0 ;
693- struct strset shown = STRSET_INIT ;
674+ kh_str_t * shown ;
675+ int hash_ret ;
694676 int do_trivial = 0 ;
695677 int do_flush = 0 ;
696678 int do_cookie = 0 ;
@@ -879,14 +861,14 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,
879861 * so walk the batch list backwards from the current head back
880862 * to the batch (sequence number) they named.
881863 *
882- * We use a strset to de-dup the list of pathnames.
864+ * We use khash to de-dup the list of pathnames.
883865 *
884866 * NEEDSWORK: each batch contains a list of interned strings,
885867 * so we only need to do pointer comparisons here to build the
886868 * hash table. Currently, we're still comparing the string
887869 * values.
888870 */
889- strset_init_with_options ( & shown , NULL , 0 );
871+ shown = kh_init_str ( );
890872 for (batch = batch_head ;
891873 batch && batch -> batch_seq_nr > requested_oldest_seq_nr ;
892874 batch = batch -> next ) {
@@ -896,9 +878,11 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,
896878 const char * s = batch -> interned_paths [k ];
897879 size_t s_len ;
898880
899- if (! strset_add ( & shown , s ))
881+ if (kh_get_str ( shown , s ) != kh_end ( shown ))
900882 duplicates ++ ;
901883 else {
884+ kh_put_str (shown , s , & hash_ret );
885+
902886 trace_printf_key (& trace_fsmonitor ,
903887 "send[%" PRIuMAX "]: %s" ,
904888 count , s );
@@ -925,6 +909,8 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,
925909 total_response_len += payload .len ;
926910 }
927911
912+ kh_release_str (shown );
913+
928914 pthread_mutex_lock (& state -> main_lock );
929915
930916 if (token_data -> client_ref_count > 0 )
@@ -968,7 +954,6 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,
968954 trace2_data_intmax ("fsmonitor" , the_repository , "response/count/duplicates" , duplicates );
969955
970956cleanup :
971- strset_clear (& shown );
972957 strbuf_release (& response_token );
973958 strbuf_release (& requested_token_id );
974959 strbuf_release (& payload );
@@ -1420,15 +1405,6 @@ static int fsmonitor_run_daemon(void)
14201405done :
14211406 pthread_cond_destroy (& state .cookies_cond );
14221407 pthread_mutex_destroy (& state .main_lock );
1423- {
1424- struct hashmap_iter iter ;
1425- struct fsmonitor_cookie_item * cookie ;
1426-
1427- hashmap_for_each_entry (& state .cookies , & iter , cookie , entry )
1428- free (cookie -> name );
1429- hashmap_clear_and_free (& state .cookies ,
1430- struct fsmonitor_cookie_item , entry );
1431- }
14321408 fsm_listen__dtor (& state );
14331409 fsm_health__dtor (& state );
14341410
@@ -1444,7 +1420,7 @@ static int fsmonitor_run_daemon(void)
14441420 return err ;
14451421}
14461422
1447- static int try_to_run_foreground_daemon (int detach_console )
1423+ static int try_to_run_foreground_daemon (int detach_console MAYBE_UNUSED )
14481424{
14491425 /*
14501426 * Technically, we don't need to probe for an existing daemon
@@ -1464,21 +1440,10 @@ static int try_to_run_foreground_daemon(int detach_console)
14641440 fflush (stderr );
14651441 }
14661442
1467- if (detach_console ) {
14681443#ifdef GIT_WINDOWS_NATIVE
1444+ if (detach_console )
14691445 FreeConsole ();
1470- #else
1471- /*
1472- * Create a new session so that the daemon is detached
1473- * from the parent's process group. This prevents
1474- * shells with job control (e.g. bash with "set -m")
1475- * from waiting on the daemon when they wait for a
1476- * foreground command that implicitly spawned it.
1477- */
1478- if (setsid () == -1 )
1479- warning_errno (_ ("setsid failed" ));
14801446#endif
1481- }
14821447
14831448 return !!fsmonitor_run_daemon ();
14841449}
@@ -1541,7 +1506,6 @@ static int try_to_start_background_daemon(void)
15411506 cp .no_stdin = 1 ;
15421507 cp .no_stdout = 1 ;
15431508 cp .no_stderr = 1 ;
1544- cp .close_fd_above_stderr = 1 ;
15451509
15461510 sbgr = start_bg_command (& cp , bg_wait_cb , NULL ,
15471511 fsmonitor__start_timeout_sec );
0 commit comments