@@ -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{
@@ -374,29 +314,16 @@ static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type
374314{
375315 void * data ;
376316
377- read_sha1_lock ();
317+ grep_read_lock ();
378318 data = read_sha1_file (sha1 , type , size );
379- read_sha1_unlock ();
380- return data ;
381- }
382-
383- static void * load_sha1 (const unsigned char * sha1 , unsigned long * size ,
384- const char * name )
385- {
386- enum object_type type ;
387- void * data = lock_and_read_sha1_file (sha1 , & type , size );
388-
389- if (!data )
390- error (_ ("'%s': unable to read %s" ), name , sha1_to_hex (sha1 ));
391-
319+ grep_read_unlock ();
392320 return data ;
393321}
394322
395323static int grep_sha1 (struct grep_opt * opt , const unsigned char * sha1 ,
396324 const char * filename , int tree_name_len )
397325{
398326 struct strbuf pathbuf = STRBUF_INIT ;
399- char * name ;
400327
401328 if (opt -> relative && opt -> prefix_length ) {
402329 quote_path_relative (filename + tree_name_len , -1 , & pathbuf ,
@@ -406,87 +333,51 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
406333 strbuf_addstr (& pathbuf , filename );
407334 }
408335
409- name = strbuf_detach (& pathbuf , NULL );
410-
411336#ifndef NO_PTHREADS
412337 if (use_threads ) {
413- grep_sha1_async (opt , name , sha1 );
338+ add_work (opt , GREP_SOURCE_SHA1 , pathbuf .buf , sha1 );
339+ strbuf_release (& pathbuf );
414340 return 0 ;
415341 } else
416342#endif
417343 {
344+ struct grep_source gs ;
418345 int hit ;
419- unsigned long sz ;
420- void * data = load_sha1 (sha1 , & sz , name );
421- if (!data )
422- hit = 0 ;
423- else
424- hit = grep_buffer (opt , name , data , sz );
425-
426- free (data );
427- free (name );
428- return hit ;
429- }
430- }
431346
432- static void * load_file (const char * filename , size_t * sz )
433- {
434- struct stat st ;
435- char * data ;
436- int i ;
347+ grep_source_init (& gs , GREP_SOURCE_SHA1 , pathbuf .buf , sha1 );
348+ strbuf_release (& pathbuf );
349+ hit = grep_source (opt , & gs );
437350
438- if (lstat (filename , & st ) < 0 ) {
439- err_ret :
440- if (errno != ENOENT )
441- error (_ ("'%s': %s" ), filename , strerror (errno ));
442- return NULL ;
443- }
444- if (!S_ISREG (st .st_mode ))
445- return NULL ;
446- * sz = xsize_t (st .st_size );
447- i = open (filename , O_RDONLY );
448- if (i < 0 )
449- goto err_ret ;
450- data = xmalloc (* sz + 1 );
451- if (st .st_size != read_in_full (i , data , * sz )) {
452- error (_ ("'%s': short read %s" ), filename , strerror (errno ));
453- close (i );
454- free (data );
455- return NULL ;
351+ grep_source_clear (& gs );
352+ return hit ;
456353 }
457- close (i );
458- data [* sz ] = 0 ;
459- return data ;
460354}
461355
462356static int grep_file (struct grep_opt * opt , const char * filename )
463357{
464358 struct strbuf buf = STRBUF_INIT ;
465- char * name ;
466359
467360 if (opt -> relative && opt -> prefix_length )
468361 quote_path_relative (filename , -1 , & buf , opt -> prefix );
469362 else
470363 strbuf_addstr (& buf , filename );
471- name = strbuf_detach (& buf , NULL );
472364
473365#ifndef NO_PTHREADS
474366 if (use_threads ) {
475- grep_file_async (opt , name , filename );
367+ add_work (opt , GREP_SOURCE_FILE , buf .buf , filename );
368+ strbuf_release (& buf );
476369 return 0 ;
477370 } else
478371#endif
479372 {
373+ struct grep_source gs ;
480374 int hit ;
481- size_t sz ;
482- void * data = load_file (filename , & sz );
483- if (!data )
484- hit = 0 ;
485- else
486- hit = grep_buffer (opt , name , data , sz );
487375
488- free (data );
489- free (name );
376+ grep_source_init (& gs , GREP_SOURCE_FILE , buf .buf , filename );
377+ strbuf_release (& buf );
378+ hit = grep_source (opt , & gs );
379+
380+ grep_source_clear (& gs );
490381 return hit ;
491382 }
492383}
@@ -615,10 +506,10 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
615506 struct strbuf base ;
616507 int hit , len ;
617508
618- read_sha1_lock ();
509+ grep_read_lock ();
619510 data = read_object_with_reference (obj -> sha1 , tree_type ,
620511 & size , NULL );
621- read_sha1_unlock ();
512+ grep_read_unlock ();
622513
623514 if (!data )
624515 die (_ ("unable to read tree (%s)" ), sha1_to_hex (obj -> sha1 ));
@@ -1030,8 +921,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
1030921 use_threads = 0 ;
1031922#endif
1032923
1033- opt .use_threads = use_threads ;
1034-
1035924#ifndef NO_PTHREADS
1036925 if (use_threads ) {
1037926 if (!(opt .name_only || opt .unmatch_name_only || opt .count )
0 commit comments