@@ -806,10 +806,46 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
806806 opt -> output (opt , "\n" , 1 );
807807}
808808
809- static int match_funcname (struct grep_opt * opt , char * bol , char * eol )
809+ #ifndef NO_PTHREADS
810+ /*
811+ * This lock protects access to the gitattributes machinery, which is
812+ * not thread-safe.
813+ */
814+ pthread_mutex_t grep_attr_mutex ;
815+
816+ static inline void grep_attr_lock (struct grep_opt * opt )
817+ {
818+ if (opt -> use_threads )
819+ pthread_mutex_lock (& grep_attr_mutex );
820+ }
821+
822+ static inline void grep_attr_unlock (struct grep_opt * opt )
823+ {
824+ if (opt -> use_threads )
825+ pthread_mutex_unlock (& grep_attr_mutex );
826+ }
827+ #else
828+ #define grep_attr_lock (opt )
829+ #define grep_attr_unlock (opt )
830+ #endif
831+
832+ static int match_funcname (struct grep_opt * opt , const char * name , char * bol , char * eol )
810833{
811834 xdemitconf_t * xecfg = opt -> priv ;
812- if (xecfg && xecfg -> find_func ) {
835+ if (xecfg && !xecfg -> find_func ) {
836+ struct userdiff_driver * drv ;
837+ grep_attr_lock (opt );
838+ drv = userdiff_find_by_path (name );
839+ grep_attr_unlock (opt );
840+ if (drv && drv -> funcname .pattern ) {
841+ const struct userdiff_funcname * pe = & drv -> funcname ;
842+ xdiff_set_find_func (xecfg , pe -> pattern , pe -> cflags );
843+ } else {
844+ xecfg = opt -> priv = NULL ;
845+ }
846+ }
847+
848+ if (xecfg ) {
813849 char buf [1 ];
814850 return xecfg -> find_func (bol , eol - bol , buf , 1 ,
815851 xecfg -> find_func_priv ) >= 0 ;
@@ -835,7 +871,7 @@ static void show_funcname_line(struct grep_opt *opt, const char *name,
835871 if (lno <= opt -> last_shown )
836872 break ;
837873
838- if (match_funcname (opt , bol , eol )) {
874+ if (match_funcname (opt , name , bol , eol )) {
839875 show_line (opt , bol , eol , name , lno , '=' );
840876 break ;
841877 }
@@ -848,7 +884,7 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
848884 unsigned cur = lno , from = 1 , funcname_lno = 0 ;
849885 int funcname_needed = !!opt -> funcname ;
850886
851- if (opt -> funcbody && !match_funcname (opt , bol , end ))
887+ if (opt -> funcbody && !match_funcname (opt , name , bol , end ))
852888 funcname_needed = 2 ;
853889
854890 if (opt -> pre_context < lno )
@@ -864,7 +900,7 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
864900 while (bol > buf && bol [-1 ] != '\n' )
865901 bol -- ;
866902 cur -- ;
867- if (funcname_needed && match_funcname (opt , bol , eol )) {
903+ if (funcname_needed && match_funcname (opt , name , bol , eol )) {
868904 funcname_lno = cur ;
869905 funcname_needed = 0 ;
870906 }
@@ -942,19 +978,6 @@ static int look_ahead(struct grep_opt *opt,
942978 return 0 ;
943979}
944980
945- int grep_threads_ok (const struct grep_opt * opt )
946- {
947- /* If this condition is true, then we may use the attribute
948- * machinery in grep_buffer_1. The attribute code is not
949- * thread safe, so we disable the use of threads.
950- */
951- if (opt -> funcname && !opt -> unmatch_name_only && !opt -> status_only &&
952- !opt -> name_only )
953- return 0 ;
954-
955- return 1 ;
956- }
957-
958981static void std_output (struct grep_opt * opt , const void * buf , size_t size )
959982{
960983 fwrite (buf , size , 1 , stdout );
@@ -1008,15 +1031,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
10081031 }
10091032
10101033 memset (& xecfg , 0 , sizeof (xecfg ));
1011- if (opt -> funcname && !opt -> unmatch_name_only && !opt -> status_only &&
1012- !opt -> name_only && !binary_match_only && !collect_hits ) {
1013- struct userdiff_driver * drv = userdiff_find_by_path (name );
1014- if (drv && drv -> funcname .pattern ) {
1015- const struct userdiff_funcname * pe = & drv -> funcname ;
1016- xdiff_set_find_func (& xecfg , pe -> pattern , pe -> cflags );
1017- opt -> priv = & xecfg ;
1018- }
1019- }
1034+ opt -> priv = & xecfg ;
1035+
10201036 try_lookahead = should_lookahead (opt );
10211037
10221038 while (left ) {
@@ -1092,7 +1108,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
10921108 show_function = 1 ;
10931109 goto next_line ;
10941110 }
1095- if (show_function && match_funcname (opt , bol , eol ))
1111+ if (show_function && match_funcname (opt , name , bol , eol ))
10961112 show_function = 0 ;
10971113 if (show_function ||
10981114 (last_hit && lno <= last_hit + opt -> post_context )) {
0 commit comments