static void work_done(struct work_item *w) { int old_done; grep_lock(); w->done = 1; old_done = todo_done; for(; todo[todo_done].done && todo_done != todo_start; todo_done = (todo_done+1) % ARRAY_SIZE(todo)) { w = &todo[todo_done]; if (w->out.len) { if (print_hunk_marks_between_files && printed_something) write_or_die(1, "--\n", 3); write_or_die(1, w->out.buf, w->out.len); printed_something = 1; } free(w->name); free(w->identifier); } if (old_done != todo_done) pthread_cond_signal(&cond_write); if (all_work_added && todo_done == todo_end) pthread_cond_signal(&cond_result); grep_unlock(); }
static int wait_all(void) { int hit = 0; int i; grep_lock(); all_work_added = 1; /* Wait until all work is done. */ while (todo_done != todo_end) pthread_cond_wait(&cond_result, &grep_mutex); /* Wake up all the consumer threads so they can see that there * is no more work to do. */ pthread_cond_broadcast(&cond_add); grep_unlock(); for (i = 0; i < ARRAY_SIZE(threads); i++) { void *h; pthread_join(threads[i], &h); hit |= (int) (intptr_t) h; } pthread_mutex_destroy(&grep_mutex); pthread_mutex_destroy(&grep_read_mutex); pthread_mutex_destroy(&grep_attr_mutex); pthread_cond_destroy(&cond_add); pthread_cond_destroy(&cond_write); pthread_cond_destroy(&cond_result); grep_use_locks = 0; return hit; }
static struct work_item *get_work(void) { struct work_item *ret; grep_lock(); while (todo_start == todo_end && !all_work_added) { pthread_cond_wait(&cond_add, &grep_mutex); } if (todo_start == todo_end && all_work_added) { ret = NULL; } else { ret = &todo[todo_start]; todo_start = (todo_start + 1) % ARRAY_SIZE(todo); } grep_unlock(); return ret; }
static void add_work(enum work_type type, char *name, void *id) { grep_lock(); while ((todo_end+1) % ARRAY_SIZE(todo) == todo_done) { pthread_cond_wait(&cond_write, &grep_mutex); } todo[todo_end].type = type; todo[todo_end].name = name; todo[todo_end].identifier = id; todo[todo_end].done = 0; strbuf_reset(&todo[todo_end].out); todo_end = (todo_end + 1) % ARRAY_SIZE(todo); pthread_cond_signal(&cond_add); grep_unlock(); }
static void add_work(struct grep_opt *opt, const struct grep_source *gs) { grep_lock(); while ((todo_end+1) % ARRAY_SIZE(todo) == todo_done) { pthread_cond_wait(&cond_write, &grep_mutex); } todo[todo_end].source = *gs; if (opt->binary != GREP_BINARY_TEXT) grep_source_load_driver(&todo[todo_end].source); todo[todo_end].done = 0; strbuf_reset(&todo[todo_end].out); todo_end = (todo_end + 1) % ARRAY_SIZE(todo); pthread_cond_signal(&cond_add); grep_unlock(); }
static void add_work(struct grep_opt *opt, enum grep_source_type type, const char *name, const char *path, const void *id) { grep_lock(); while ((todo_end+1) % ARRAY_SIZE(todo) == todo_done) { pthread_cond_wait(&cond_write, &grep_mutex); } grep_source_init(&todo[todo_end].source, type, name, path, id); if (opt->binary != GREP_BINARY_TEXT) grep_source_load_driver(&todo[todo_end].source); todo[todo_end].done = 0; strbuf_reset(&todo[todo_end].out); todo_end = (todo_end + 1) % ARRAY_SIZE(todo); pthread_cond_signal(&cond_add); grep_unlock(); }
static void work_done(struct work_item *w) { int old_done; grep_lock(); w->done = 1; old_done = todo_done; for(; todo[todo_done].done && todo_done != todo_start; todo_done = (todo_done+1) % ARRAY_SIZE(todo)) { w = &todo[todo_done]; if (w->out.len) { const char *p = w->out.buf; size_t len = w->out.len; /* Skip the leading hunk mark of the first file. */ if (skip_first_line) { while (len) { len--; if (*p++ == '\n') break; } skip_first_line = 0; } write_or_die(1, p, len); } free(w->name); free(w->identifier); } if (old_done != todo_done) pthread_cond_signal(&cond_write); if (all_work_added && todo_done == todo_end) pthread_cond_signal(&cond_result); grep_unlock(); }
static void work_done(struct work_item *w) { int old_done; grep_lock(); w->done = 1; old_done = todo_done; for(; todo[todo_done].done && todo_done != todo_start; todo_done = (todo_done+1) % ARRAY_SIZE(todo)) { w = &todo[todo_done]; write_or_die(1, w->out.buf, w->out.len); free(w->name); free(w->identifier); } if (old_done != todo_done) pthread_cond_signal(&cond_write); if (all_work_added && todo_done == todo_end) pthread_cond_signal(&cond_result); grep_unlock(); }