@@ -29,25 +29,12 @@ static int use_threads = 1;
2929#define THREADS 8
3030static pthread_t threads [THREADS ];
3131
32- static void * load_sha1 (const unsigned char * sha1 , unsigned long * size ,
33- const char * name );
34- static void * load_file (const char * filename , size_t * sz );
35-
36- enum work_type {WORK_SHA1 , WORK_FILE };
37-
3832/* We use one producer thread and THREADS consumer
3933 * threads. The producer adds struct work_items to 'todo' and the
4034 * consumers pick work items from the same array.
4135 */
4236struct work_item {
43- enum work_type type ;
44- char * name ;
45-
46- /* if type == WORK_SHA1, then 'identifier' is a SHA1,
47- * otherwise type == WORK_FILE, and 'identifier' is a NUL
48- * terminated filename.
49- */
50- void * identifier ;
37+ struct grep_source source ;
5138 char done ;
5239 struct strbuf out ;
5340};
@@ -85,21 +72,6 @@ static inline void grep_unlock(void)
8572 pthread_mutex_unlock (& grep_mutex );
8673}
8774
88- /* Used to serialize calls to read_sha1_file. */
89- static pthread_mutex_t read_sha1_mutex ;
90-
91- static inline void read_sha1_lock (void )
92- {
93- if (use_threads )
94- pthread_mutex_lock (& read_sha1_mutex );
95- }
96-
97- static inline void read_sha1_unlock (void )
98- {
99- if (use_threads )
100- pthread_mutex_unlock (& read_sha1_mutex );
101- }
102-
10375/* Signalled when a new work_item is added to todo. */
10476static pthread_cond_t cond_add ;
10577
@@ -113,17 +85,18 @@ static pthread_cond_t cond_result;
11385
11486static int skip_first_line ;
11587
116- static void add_work (enum work_type type , char * name , void * id )
88+ static void add_work (struct grep_opt * opt , enum grep_source_type type ,
89+ const char * name , const void * id )
11790{
11891 grep_lock ();
11992
12093 while ((todo_end + 1 ) % ARRAY_SIZE (todo ) == todo_done ) {
12194 pthread_cond_wait (& cond_write , & grep_mutex );
12295 }
12396
124- todo [todo_end ].type = type ;
125- todo [ todo_end ]. name = name ;
126- todo [todo_end ].identifier = id ;
97+ grep_source_init ( & todo [todo_end ].source , type , name , id ) ;
98+ if ( opt -> binary != GREP_BINARY_TEXT )
99+ grep_source_load_driver ( & todo [todo_end ].source ) ;
127100 todo [todo_end ].done = 0 ;
128101 strbuf_reset (& todo [todo_end ].out );
129102 todo_end = (todo_end + 1 ) % ARRAY_SIZE (todo );
@@ -151,21 +124,6 @@ static struct work_item *get_work(void)
151124 return ret ;
152125}
153126
154- static void grep_sha1_async (struct grep_opt * opt , char * name ,
155- const unsigned char * sha1 )
156- {
157- unsigned char * s ;
158- s = xmalloc (20 );
159- memcpy (s , sha1 , 20 );
160- add_work (WORK_SHA1 , name , s );
161- }
162-
163- static void grep_file_async (struct grep_opt * opt , char * name ,
164- const char * filename )
165- {
166- add_work (WORK_FILE , name , xstrdup (filename ));
167- }
168-
169127static void work_done (struct work_item * w )
170128{
171129 int old_done ;
@@ -192,8 +150,7 @@ static void work_done(struct work_item *w)
192150
193151 write_or_die (1 , p , len );
194152 }
195- free (w -> name );
196- free (w -> identifier );
153+ grep_source_clear (& w -> source );
197154 }
198155
199156 if (old_done != todo_done )
@@ -216,25 +173,8 @@ static void *run(void *arg)
216173 break ;
217174
218175 opt -> output_priv = w ;
219- if (w -> type == WORK_SHA1 ) {
220- unsigned long sz ;
221- void * data = load_sha1 (w -> identifier , & sz , w -> name );
222-
223- if (data ) {
224- hit |= grep_buffer (opt , w -> name , data , sz );
225- free (data );
226- }
227- } else if (w -> type == WORK_FILE ) {
228- size_t sz ;
229- void * data = load_file (w -> identifier , & sz );
230- if (data ) {
231- hit |= grep_buffer (opt , w -> name , data , sz );
232- free (data );
233- }
234- } else {
235- assert (0 );
236- }
237-
176+ hit |= grep_source (opt , & w -> source );
177+ grep_source_clear_data (& w -> source );
238178 work_done (w );
239179 }
240180 free_grep_patterns (arg );
@@ -254,11 +194,12 @@ static void start_threads(struct grep_opt *opt)
254194 int i ;
255195
256196 pthread_mutex_init (& grep_mutex , NULL );
257- pthread_mutex_init (& read_sha1_mutex , NULL );
197+ pthread_mutex_init (& grep_read_mutex , NULL );
258198 pthread_mutex_init (& grep_attr_mutex , NULL );
259199 pthread_cond_init (& cond_add , NULL );
260200 pthread_cond_init (& cond_write , NULL );
261201 pthread_cond_init (& cond_result , NULL );
202+ grep_use_locks = 1 ;
262203
263204 for (i = 0 ; i < ARRAY_SIZE (todo ); i ++ ) {
264205 strbuf_init (& todo [i ].out , 0 );
@@ -302,17 +243,16 @@ static int wait_all(void)
302243 }
303244
304245 pthread_mutex_destroy (& grep_mutex );
305- pthread_mutex_destroy (& read_sha1_mutex );
246+ pthread_mutex_destroy (& grep_read_mutex );
306247 pthread_mutex_destroy (& grep_attr_mutex );
307248 pthread_cond_destroy (& cond_add );
308249 pthread_cond_destroy (& cond_write );
309250 pthread_cond_destroy (& cond_result );
251+ grep_use_locks = 0 ;
310252
311253 return hit ;
312254}
313255#else /* !NO_PTHREADS */
314- #define read_sha1_lock ()
315- #define read_sha1_unlock ()
316256
317257static int wait_all (void )
318258{
@@ -371,29 +311,16 @@ static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type
371311{
372312 void * data ;
373313
374- read_sha1_lock ();
314+ grep_read_lock ();
375315 data = read_sha1_file (sha1 , type , size );
376- read_sha1_unlock ();
377- return data ;
378- }
379-
380- static void * load_sha1 (const unsigned char * sha1 , unsigned long * size ,
381- const char * name )
382- {
383- enum object_type type ;
384- void * data = lock_and_read_sha1_file (sha1 , & type , size );
385-
386- if (!data )
387- error (_ ("'%s': unable to read %s" ), name , sha1_to_hex (sha1 ));
388-
316+ grep_read_unlock ();
389317 return data ;
390318}
391319
392320static int grep_sha1 (struct grep_opt * opt , const unsigned char * sha1 ,
393321 const char * filename , int tree_name_len )
394322{
395323 struct strbuf pathbuf = STRBUF_INIT ;
396- char * name ;
397324
398325 if (opt -> relative && opt -> prefix_length ) {
399326 quote_path_relative (filename + tree_name_len , -1 , & pathbuf ,
@@ -403,87 +330,51 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
403330 strbuf_addstr (& pathbuf , filename );
404331 }
405332
406- name = strbuf_detach (& pathbuf , NULL );
407-
408333#ifndef NO_PTHREADS
409334 if (use_threads ) {
410- grep_sha1_async (opt , name , sha1 );
335+ add_work (opt , GREP_SOURCE_SHA1 , pathbuf .buf , sha1 );
336+ strbuf_release (& pathbuf );
411337 return 0 ;
412338 } else
413339#endif
414340 {
341+ struct grep_source gs ;
415342 int hit ;
416- unsigned long sz ;
417- void * data = load_sha1 (sha1 , & sz , name );
418- if (!data )
419- hit = 0 ;
420- else
421- hit = grep_buffer (opt , name , data , sz );
422-
423- free (data );
424- free (name );
425- return hit ;
426- }
427- }
428343
429- static void * load_file (const char * filename , size_t * sz )
430- {
431- struct stat st ;
432- char * data ;
433- int i ;
344+ grep_source_init (& gs , GREP_SOURCE_SHA1 , pathbuf .buf , sha1 );
345+ strbuf_release (& pathbuf );
346+ hit = grep_source (opt , & gs );
434347
435- if (lstat (filename , & st ) < 0 ) {
436- err_ret :
437- if (errno != ENOENT )
438- error (_ ("'%s': %s" ), filename , strerror (errno ));
439- return NULL ;
440- }
441- if (!S_ISREG (st .st_mode ))
442- return NULL ;
443- * sz = xsize_t (st .st_size );
444- i = open (filename , O_RDONLY );
445- if (i < 0 )
446- goto err_ret ;
447- data = xmalloc (* sz + 1 );
448- if (st .st_size != read_in_full (i , data , * sz )) {
449- error (_ ("'%s': short read %s" ), filename , strerror (errno ));
450- close (i );
451- free (data );
452- return NULL ;
348+ grep_source_clear (& gs );
349+ return hit ;
453350 }
454- close (i );
455- data [* sz ] = 0 ;
456- return data ;
457351}
458352
459353static int grep_file (struct grep_opt * opt , const char * filename )
460354{
461355 struct strbuf buf = STRBUF_INIT ;
462- char * name ;
463356
464357 if (opt -> relative && opt -> prefix_length )
465358 quote_path_relative (filename , -1 , & buf , opt -> prefix );
466359 else
467360 strbuf_addstr (& buf , filename );
468- name = strbuf_detach (& buf , NULL );
469361
470362#ifndef NO_PTHREADS
471363 if (use_threads ) {
472- grep_file_async (opt , name , filename );
364+ add_work (opt , GREP_SOURCE_FILE , buf .buf , filename );
365+ strbuf_release (& buf );
473366 return 0 ;
474367 } else
475368#endif
476369 {
370+ struct grep_source gs ;
477371 int hit ;
478- size_t sz ;
479- void * data = load_file (filename , & sz );
480- if (!data )
481- hit = 0 ;
482- else
483- hit = grep_buffer (opt , name , data , sz );
484372
485- free (data );
486- free (name );
373+ grep_source_init (& gs , GREP_SOURCE_FILE , buf .buf , filename );
374+ strbuf_release (& buf );
375+ hit = grep_source (opt , & gs );
376+
377+ grep_source_clear (& gs );
487378 return hit ;
488379 }
489380}
@@ -612,10 +503,10 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
612503 struct strbuf base ;
613504 int hit , len ;
614505
615- read_sha1_lock ();
506+ grep_read_lock ();
616507 data = read_object_with_reference (obj -> sha1 , tree_type ,
617508 & size , NULL );
618- read_sha1_unlock ();
509+ grep_read_unlock ();
619510
620511 if (!data )
621512 die (_ ("unable to read tree (%s)" ), sha1_to_hex (obj -> sha1 ));
@@ -1027,8 +918,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
1027918 use_threads = 0 ;
1028919#endif
1029920
1030- opt .use_threads = use_threads ;
1031-
1032921#ifndef NO_PTHREADS
1033922 if (use_threads ) {
1034923 if (!(opt .name_only || opt .unmatch_name_only || opt .count )
0 commit comments