File src/Makefile.in changed (mode: 100644) (index 9f594585c..c7bafe133) |
... |
... |
am_vifm_OBJECTS = cfg/config.$(OBJEXT) cfg/info.$(OBJEXT) \ |
198 |
198 |
ui/quickview.$(OBJEXT) ui/statusbar.$(OBJEXT) \ |
ui/quickview.$(OBJEXT) ui/statusbar.$(OBJEXT) \ |
199 |
199 |
ui/statusline.$(OBJEXT) ui/tabs.$(OBJEXT) ui/ui.$(OBJEXT) \ |
ui/statusline.$(OBJEXT) ui/tabs.$(OBJEXT) ui/ui.$(OBJEXT) \ |
200 |
200 |
utils/cancellation.$(OBJEXT) utils/dynarray.$(OBJEXT) \ |
utils/cancellation.$(OBJEXT) utils/dynarray.$(OBJEXT) \ |
201 |
|
utils/env.$(OBJEXT) utils/file_streams.$(OBJEXT) \ |
|
202 |
|
utils/filemon.$(OBJEXT) utils/filter.$(OBJEXT) \ |
|
203 |
|
utils/fs.$(OBJEXT) utils/fsdata.$(OBJEXT) \ |
|
204 |
|
utils/fsddata.$(OBJEXT) utils/fswatch_nix.$(OBJEXT) \ |
|
205 |
|
utils/globs.$(OBJEXT) utils/gmux_nix.$(OBJEXT) \ |
|
206 |
|
utils/hist.$(OBJEXT) utils/int_stack.$(OBJEXT) \ |
|
207 |
|
utils/log.$(OBJEXT) utils/matcher.$(OBJEXT) \ |
|
208 |
|
utils/matchers.$(OBJEXT) utils/mem.$(OBJEXT) \ |
|
209 |
|
utils/parson.$(OBJEXT) utils/path.$(OBJEXT) \ |
|
210 |
|
utils/regexp.$(OBJEXT) utils/selector_nix.$(OBJEXT) \ |
|
211 |
|
utils/shmem_nix.$(OBJEXT) utils/str.$(OBJEXT) \ |
|
212 |
|
utils/string_array.$(OBJEXT) utils/trie.$(OBJEXT) \ |
|
213 |
|
utils/utf8.$(OBJEXT) utils/utf8proc.$(OBJEXT) \ |
|
214 |
|
utils/utils.$(OBJEXT) utils/utils_nix.$(OBJEXT) args.$(OBJEXT) \ |
|
215 |
|
background.$(OBJEXT) bmarks.$(OBJEXT) \ |
|
216 |
|
bracket_notation.$(OBJEXT) builtin_functions.$(OBJEXT) \ |
|
217 |
|
cmd_actions.$(OBJEXT) cmd_completion.$(OBJEXT) \ |
|
218 |
|
cmd_core.$(OBJEXT) cmd_handlers.$(OBJEXT) compare.$(OBJEXT) \ |
|
219 |
|
dir_stack.$(OBJEXT) event_loop.$(OBJEXT) filelist.$(OBJEXT) \ |
|
|
201 |
|
utils/env.$(OBJEXT) utils/event_nix.$(OBJEXT) \ |
|
202 |
|
utils/file_streams.$(OBJEXT) utils/filemon.$(OBJEXT) \ |
|
203 |
|
utils/filter.$(OBJEXT) utils/fs.$(OBJEXT) \ |
|
204 |
|
utils/fsdata.$(OBJEXT) utils/fsddata.$(OBJEXT) \ |
|
205 |
|
utils/fswatch_nix.$(OBJEXT) utils/globs.$(OBJEXT) \ |
|
206 |
|
utils/gmux_nix.$(OBJEXT) utils/hist.$(OBJEXT) \ |
|
207 |
|
utils/int_stack.$(OBJEXT) utils/log.$(OBJEXT) \ |
|
208 |
|
utils/matcher.$(OBJEXT) utils/matchers.$(OBJEXT) \ |
|
209 |
|
utils/mem.$(OBJEXT) utils/parson.$(OBJEXT) \ |
|
210 |
|
utils/path.$(OBJEXT) utils/regexp.$(OBJEXT) \ |
|
211 |
|
utils/selector_nix.$(OBJEXT) utils/shmem_nix.$(OBJEXT) \ |
|
212 |
|
utils/str.$(OBJEXT) utils/string_array.$(OBJEXT) \ |
|
213 |
|
utils/trie.$(OBJEXT) utils/utf8.$(OBJEXT) \ |
|
214 |
|
utils/utf8proc.$(OBJEXT) utils/utils.$(OBJEXT) \ |
|
215 |
|
utils/utils_nix.$(OBJEXT) args.$(OBJEXT) background.$(OBJEXT) \ |
|
216 |
|
bmarks.$(OBJEXT) bracket_notation.$(OBJEXT) \ |
|
217 |
|
builtin_functions.$(OBJEXT) cmd_actions.$(OBJEXT) \ |
|
218 |
|
cmd_completion.$(OBJEXT) cmd_core.$(OBJEXT) \ |
|
219 |
|
cmd_handlers.$(OBJEXT) compare.$(OBJEXT) dir_stack.$(OBJEXT) \ |
|
220 |
|
event_loop.$(OBJEXT) filelist.$(OBJEXT) \ |
220 |
221 |
filename_modifiers.$(OBJEXT) fops_common.$(OBJEXT) \ |
filename_modifiers.$(OBJEXT) fops_common.$(OBJEXT) \ |
221 |
222 |
fops_cpmv.$(OBJEXT) fops_misc.$(OBJEXT) fops_put.$(OBJEXT) \ |
fops_cpmv.$(OBJEXT) fops_misc.$(OBJEXT) fops_put.$(OBJEXT) \ |
222 |
223 |
fops_rename.$(OBJEXT) filetype.$(OBJEXT) filtering.$(OBJEXT) \ |
fops_rename.$(OBJEXT) filetype.$(OBJEXT) filtering.$(OBJEXT) \ |
|
... |
... |
am__depfiles_remade = ./$(DEPDIR)/args.Po ./$(DEPDIR)/background.Po \ |
371 |
372 |
ui/$(DEPDIR)/statusbar.Po ui/$(DEPDIR)/statusline.Po \ |
ui/$(DEPDIR)/statusbar.Po ui/$(DEPDIR)/statusline.Po \ |
372 |
373 |
ui/$(DEPDIR)/tabs.Po ui/$(DEPDIR)/ui.Po \ |
ui/$(DEPDIR)/tabs.Po ui/$(DEPDIR)/ui.Po \ |
373 |
374 |
utils/$(DEPDIR)/cancellation.Po utils/$(DEPDIR)/dynarray.Po \ |
utils/$(DEPDIR)/cancellation.Po utils/$(DEPDIR)/dynarray.Po \ |
374 |
|
utils/$(DEPDIR)/env.Po utils/$(DEPDIR)/file_streams.Po \ |
|
375 |
|
utils/$(DEPDIR)/filemon.Po utils/$(DEPDIR)/filter.Po \ |
|
376 |
|
utils/$(DEPDIR)/fs.Po utils/$(DEPDIR)/fsdata.Po \ |
|
377 |
|
utils/$(DEPDIR)/fsddata.Po utils/$(DEPDIR)/fswatch_nix.Po \ |
|
378 |
|
utils/$(DEPDIR)/globs.Po utils/$(DEPDIR)/gmux_nix.Po \ |
|
379 |
|
utils/$(DEPDIR)/hist.Po utils/$(DEPDIR)/int_stack.Po \ |
|
380 |
|
utils/$(DEPDIR)/log.Po utils/$(DEPDIR)/matcher.Po \ |
|
381 |
|
utils/$(DEPDIR)/matchers.Po utils/$(DEPDIR)/mem.Po \ |
|
382 |
|
utils/$(DEPDIR)/parson.Po utils/$(DEPDIR)/path.Po \ |
|
383 |
|
utils/$(DEPDIR)/regexp.Po utils/$(DEPDIR)/selector_nix.Po \ |
|
384 |
|
utils/$(DEPDIR)/shmem_nix.Po utils/$(DEPDIR)/str.Po \ |
|
385 |
|
utils/$(DEPDIR)/string_array.Po utils/$(DEPDIR)/trie.Po \ |
|
386 |
|
utils/$(DEPDIR)/utf8.Po utils/$(DEPDIR)/utf8proc.Po \ |
|
387 |
|
utils/$(DEPDIR)/utils.Po utils/$(DEPDIR)/utils_nix.Po |
|
|
375 |
|
utils/$(DEPDIR)/env.Po utils/$(DEPDIR)/event_nix.Po \ |
|
376 |
|
utils/$(DEPDIR)/file_streams.Po utils/$(DEPDIR)/filemon.Po \ |
|
377 |
|
utils/$(DEPDIR)/filter.Po utils/$(DEPDIR)/fs.Po \ |
|
378 |
|
utils/$(DEPDIR)/fsdata.Po utils/$(DEPDIR)/fsddata.Po \ |
|
379 |
|
utils/$(DEPDIR)/fswatch_nix.Po utils/$(DEPDIR)/globs.Po \ |
|
380 |
|
utils/$(DEPDIR)/gmux_nix.Po utils/$(DEPDIR)/hist.Po \ |
|
381 |
|
utils/$(DEPDIR)/int_stack.Po utils/$(DEPDIR)/log.Po \ |
|
382 |
|
utils/$(DEPDIR)/matcher.Po utils/$(DEPDIR)/matchers.Po \ |
|
383 |
|
utils/$(DEPDIR)/mem.Po utils/$(DEPDIR)/parson.Po \ |
|
384 |
|
utils/$(DEPDIR)/path.Po utils/$(DEPDIR)/regexp.Po \ |
|
385 |
|
utils/$(DEPDIR)/selector_nix.Po utils/$(DEPDIR)/shmem_nix.Po \ |
|
386 |
|
utils/$(DEPDIR)/str.Po utils/$(DEPDIR)/string_array.Po \ |
|
387 |
|
utils/$(DEPDIR)/trie.Po utils/$(DEPDIR)/utf8.Po \ |
|
388 |
|
utils/$(DEPDIR)/utf8proc.Po utils/$(DEPDIR)/utils.Po \ |
|
389 |
|
utils/$(DEPDIR)/utils_nix.Po |
388 |
390 |
am__mv = mv -f |
am__mv = mv -f |
389 |
391 |
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ |
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ |
390 |
392 |
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
|
... |
... |
vifm_SOURCES = \ |
985 |
987 |
utils/darray.h \ |
utils/darray.h \ |
986 |
988 |
utils/dynarray.c utils/dynarray.h \ |
utils/dynarray.c utils/dynarray.h \ |
987 |
989 |
utils/env.c utils/env.h \ |
utils/env.c utils/env.h \ |
|
990 |
|
utils/event_nix.c utils/event.h \ |
988 |
991 |
utils/file_streams.c utils/file_streams.h \ |
utils/file_streams.c utils/file_streams.h \ |
989 |
992 |
utils/filemon.c utils/filemon.h \ |
utils/filemon.c utils/filemon.h \ |
990 |
993 |
utils/filter.c utils/filter.h \ |
utils/filter.c utils/filter.h \ |
|
... |
... |
utils/dynarray.$(OBJEXT): utils/$(am__dirstamp) \ |
1520 |
1523 |
utils/$(DEPDIR)/$(am__dirstamp) |
utils/$(DEPDIR)/$(am__dirstamp) |
1521 |
1524 |
utils/env.$(OBJEXT): utils/$(am__dirstamp) \ |
utils/env.$(OBJEXT): utils/$(am__dirstamp) \ |
1522 |
1525 |
utils/$(DEPDIR)/$(am__dirstamp) |
utils/$(DEPDIR)/$(am__dirstamp) |
|
1526 |
|
utils/event_nix.$(OBJEXT): utils/$(am__dirstamp) \ |
|
1527 |
|
utils/$(DEPDIR)/$(am__dirstamp) |
1523 |
1528 |
utils/file_streams.$(OBJEXT): utils/$(am__dirstamp) \ |
utils/file_streams.$(OBJEXT): utils/$(am__dirstamp) \ |
1524 |
1529 |
utils/$(DEPDIR)/$(am__dirstamp) |
utils/$(DEPDIR)/$(am__dirstamp) |
1525 |
1530 |
utils/filemon.$(OBJEXT): utils/$(am__dirstamp) \ |
utils/filemon.$(OBJEXT): utils/$(am__dirstamp) \ |
|
... |
... |
distclean-compile: |
1852 |
1857 |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/cancellation.Po@am__quote@ # am--include-marker |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/cancellation.Po@am__quote@ # am--include-marker |
1853 |
1858 |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/dynarray.Po@am__quote@ # am--include-marker |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/dynarray.Po@am__quote@ # am--include-marker |
1854 |
1859 |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/env.Po@am__quote@ # am--include-marker |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/env.Po@am__quote@ # am--include-marker |
|
1860 |
|
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/event_nix.Po@am__quote@ # am--include-marker |
1855 |
1861 |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/file_streams.Po@am__quote@ # am--include-marker |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/file_streams.Po@am__quote@ # am--include-marker |
1856 |
1862 |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/filemon.Po@am__quote@ # am--include-marker |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/filemon.Po@am__quote@ # am--include-marker |
1857 |
1863 |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/filter.Po@am__quote@ # am--include-marker |
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/filter.Po@am__quote@ # am--include-marker |
|
... |
... |
distclean: distclean-am |
2892 |
2898 |
-rm -f utils/$(DEPDIR)/cancellation.Po |
-rm -f utils/$(DEPDIR)/cancellation.Po |
2893 |
2899 |
-rm -f utils/$(DEPDIR)/dynarray.Po |
-rm -f utils/$(DEPDIR)/dynarray.Po |
2894 |
2900 |
-rm -f utils/$(DEPDIR)/env.Po |
-rm -f utils/$(DEPDIR)/env.Po |
|
2901 |
|
-rm -f utils/$(DEPDIR)/event_nix.Po |
2895 |
2902 |
-rm -f utils/$(DEPDIR)/file_streams.Po |
-rm -f utils/$(DEPDIR)/file_streams.Po |
2896 |
2903 |
-rm -f utils/$(DEPDIR)/filemon.Po |
-rm -f utils/$(DEPDIR)/filemon.Po |
2897 |
2904 |
-rm -f utils/$(DEPDIR)/filter.Po |
-rm -f utils/$(DEPDIR)/filter.Po |
|
... |
... |
maintainer-clean: maintainer-clean-am |
3159 |
3166 |
-rm -f utils/$(DEPDIR)/cancellation.Po |
-rm -f utils/$(DEPDIR)/cancellation.Po |
3160 |
3167 |
-rm -f utils/$(DEPDIR)/dynarray.Po |
-rm -f utils/$(DEPDIR)/dynarray.Po |
3161 |
3168 |
-rm -f utils/$(DEPDIR)/env.Po |
-rm -f utils/$(DEPDIR)/env.Po |
|
3169 |
|
-rm -f utils/$(DEPDIR)/event_nix.Po |
3162 |
3170 |
-rm -f utils/$(DEPDIR)/file_streams.Po |
-rm -f utils/$(DEPDIR)/file_streams.Po |
3163 |
3171 |
-rm -f utils/$(DEPDIR)/filemon.Po |
-rm -f utils/$(DEPDIR)/filemon.Po |
3164 |
3172 |
-rm -f utils/$(DEPDIR)/filter.Po |
-rm -f utils/$(DEPDIR)/filter.Po |
File src/background.c changed (mode: 100644) (index 4183f545c..523dbfc67) |
49 |
49 |
#include "ui/ui.h" |
#include "ui/ui.h" |
50 |
50 |
#include "utils/cancellation.h" |
#include "utils/cancellation.h" |
51 |
51 |
#include "utils/env.h" |
#include "utils/env.h" |
|
52 |
|
#include "utils/event.h" |
52 |
53 |
#include "utils/fs.h" |
#include "utils/fs.h" |
53 |
54 |
#include "utils/log.h" |
#include "utils/log.h" |
54 |
55 |
#include "utils/path.h" |
#include "utils/path.h" |
|
... |
... |
static bg_job_t * add_background_job(pid_t pid, const char cmd[], |
135 |
136 |
static void * background_task_bootstrap(void *arg); |
static void * background_task_bootstrap(void *arg); |
136 |
137 |
static int update_job_status(bg_job_t *job); |
static int update_job_status(bg_job_t *job); |
137 |
138 |
static void mark_job_finished(bg_job_t *job, int exit_code); |
static void mark_job_finished(bg_job_t *job, int exit_code); |
|
139 |
|
static void poke_error_thread(void); |
138 |
140 |
static int bg_op_cancel(bg_op_t *bg_op); |
static int bg_op_cancel(bg_op_t *bg_op); |
139 |
141 |
|
|
140 |
142 |
bg_job_t *bg_jobs = NULL; |
bg_job_t *bg_jobs = NULL; |
141 |
143 |
|
|
|
144 |
|
/* Event to wake up error thread from sleep for processing by |
|
145 |
|
* poke_error_thread(). */ |
|
146 |
|
static event_t *error_thread_event; |
142 |
147 |
/* Head of list of newly started jobs. */ |
/* Head of list of newly started jobs. */ |
143 |
148 |
static bg_job_t *new_err_jobs; |
static bg_job_t *new_err_jobs; |
144 |
149 |
/* Mutex to protect new_err_jobs. */ |
/* Mutex to protect new_err_jobs. */ |
|
... |
... |
static pthread_key_t current_job; |
152 |
157 |
int |
int |
153 |
158 |
bg_init(void) |
bg_init(void) |
154 |
159 |
{ |
{ |
|
160 |
|
error_thread_event = event_alloc(); |
|
161 |
|
if(error_thread_event == NULL) |
|
162 |
|
{ |
|
163 |
|
return 1; |
|
164 |
|
} |
|
165 |
|
|
155 |
166 |
/* Create thread-local storage before starting any background threads. */ |
/* Create thread-local storage before starting any background threads. */ |
156 |
167 |
if(pthread_key_create(¤t_job, NULL) != 0) |
if(pthread_key_create(¤t_job, NULL) != 0) |
157 |
168 |
{ |
{ |
|
169 |
|
event_free(error_thread_event); |
158 |
170 |
return 1; |
return 1; |
159 |
171 |
} |
} |
160 |
172 |
|
|
|
... |
... |
bg_init(void) |
162 |
174 |
if(pthread_create(&id, NULL, &error_thread, NULL) != 0) |
if(pthread_create(&id, NULL, &error_thread, NULL) != 0) |
163 |
175 |
{ |
{ |
164 |
176 |
pthread_key_delete(current_job); |
pthread_key_delete(current_job); |
|
177 |
|
event_free(error_thread_event); |
165 |
178 |
return 1; |
return 1; |
166 |
179 |
} |
} |
167 |
180 |
|
|
|
... |
... |
bg_check(void) |
183 |
196 |
return; |
return; |
184 |
197 |
} |
} |
185 |
198 |
|
|
|
199 |
|
poke_error_thread(); |
|
200 |
|
|
186 |
201 |
int active_jobs = 0; |
int active_jobs = 0; |
187 |
202 |
|
|
188 |
203 |
bg_job_t *head = bg_jobs; |
bg_job_t *head = bg_jobs; |
|
... |
... |
error_thread(void *p) |
427 |
442 |
(void)pthread_detach(pthread_self()); |
(void)pthread_detach(pthread_self()); |
428 |
443 |
block_all_thread_signals(); |
block_all_thread_signals(); |
429 |
444 |
|
|
|
445 |
|
const event_end_t event_end = event_wait_end(error_thread_event); |
|
446 |
|
|
430 |
447 |
while(1) |
while(1) |
431 |
448 |
{ |
{ |
432 |
449 |
update_error_jobs(&jobs); |
update_error_jobs(&jobs); |
433 |
450 |
make_ready_list(jobs, selector); |
make_ready_list(jobs, selector); |
|
451 |
|
selector_add(selector, event_end); |
434 |
452 |
while(selector_wait(selector, ERROR_SELECT_TIMEOUT_MS)) |
while(selector_wait(selector, ERROR_SELECT_TIMEOUT_MS)) |
435 |
453 |
{ |
{ |
436 |
454 |
int need_update_list = (jobs == NULL); |
int need_update_list = (jobs == NULL); |
437 |
455 |
|
|
|
456 |
|
if(selector_is_ready(selector, event_end)) |
|
457 |
|
{ |
|
458 |
|
(void)event_reset(error_thread_event); |
|
459 |
|
} |
|
460 |
|
|
438 |
461 |
bg_job_t **job = &jobs; |
bg_job_t **job = &jobs; |
439 |
462 |
while(*job != NULL) |
while(*job != NULL) |
440 |
463 |
{ |
{ |
|
... |
... |
error_thread(void *p) |
442 |
465 |
char err_msg[ERR_MSG_LEN]; |
char err_msg[ERR_MSG_LEN]; |
443 |
466 |
ssize_t nread; |
ssize_t nread; |
444 |
467 |
|
|
|
468 |
|
if(j->drained) |
|
469 |
|
{ |
|
470 |
|
/* List update drops jobs which aren't running anymore thus allowing |
|
471 |
|
* them to be gone. Matters at least in tests which wait for all |
|
472 |
|
* tasks to finish and looping here leads to a timeout. */ |
|
473 |
|
need_update_list = 1; |
|
474 |
|
goto next_job; |
|
475 |
|
} |
|
476 |
|
|
445 |
477 |
if(!selector_is_ready(selector, j->err_stream)) |
if(!selector_is_ready(selector, j->err_stream)) |
446 |
478 |
{ |
{ |
447 |
479 |
goto next_job; |
goto next_job; |
|
... |
... |
error_thread(void *p) |
458 |
490 |
nread = bytes_read; |
nread = bytes_read; |
459 |
491 |
} |
} |
460 |
492 |
#endif |
#endif |
461 |
|
if(nread < 0) |
|
|
493 |
|
if(nread > 0) |
462 |
494 |
{ |
{ |
463 |
|
need_update_list = 1; |
|
464 |
|
j->drained = 1; |
|
465 |
|
goto next_job; |
|
|
495 |
|
err_msg[nread] = '\0'; |
|
496 |
|
append_error_msg(j, err_msg); |
466 |
497 |
} |
} |
467 |
|
|
|
468 |
|
if(nread == 0) |
|
|
498 |
|
else |
469 |
499 |
{ |
{ |
470 |
|
/* Reached EOF, exclude corresponding file descriptor from the set, |
|
471 |
|
* cut the job out of our list and decrement its use counter. */ |
|
472 |
|
selector_remove(selector, j->err_stream); |
|
473 |
|
*job = j->err_next; |
|
474 |
|
bg_job_decref(j); |
|
475 |
|
continue; |
|
|
500 |
|
/* EOF or some error. */ |
|
501 |
|
need_update_list = 1; |
|
502 |
|
j->drained = 1; |
476 |
503 |
} |
} |
477 |
504 |
|
|
478 |
|
err_msg[nread] = '\0'; |
|
479 |
|
append_error_msg(j, err_msg); |
|
480 |
|
|
|
481 |
505 |
next_job: |
next_job: |
482 |
506 |
job = &j->err_next; |
job = &j->err_next; |
483 |
507 |
} |
} |
|
... |
... |
error_thread(void *p) |
495 |
519 |
} |
} |
496 |
520 |
|
|
497 |
521 |
selector_free(selector); |
selector_free(selector); |
|
522 |
|
event_free(error_thread_event); |
498 |
523 |
return NULL; |
return NULL; |
499 |
524 |
} |
} |
500 |
525 |
|
|
|
... |
... |
mark_job_finished(bg_job_t *job, int exit_code) |
1667 |
1692 |
} |
} |
1668 |
1693 |
} |
} |
1669 |
1694 |
|
|
|
1695 |
|
/* Wakes up error thread to process any changes to the jobs. */ |
|
1696 |
|
static void |
|
1697 |
|
poke_error_thread(void) |
|
1698 |
|
{ |
|
1699 |
|
(void)event_signal(error_thread_event); |
|
1700 |
|
} |
|
1701 |
|
|
1670 |
1702 |
void |
void |
1671 |
1703 |
bg_job_incref(bg_job_t *job) |
bg_job_incref(bg_job_t *job) |
1672 |
1704 |
{ |
{ |
File src/utils/event.h added (mode: 100644) (index 000000000..c1ea4f798) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2024 xaizek. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
#ifndef VIFM__UTILS__EVENT_H__ |
|
20 |
|
#define VIFM__UTILS__EVENT_H__ |
|
21 |
|
|
|
22 |
|
/* This unit is meant to provide abstraction over platform-specific mechanism |
|
23 |
|
* for interrupting select()-like API call. It implements a manual-reset |
|
24 |
|
* event. */ |
|
25 |
|
|
|
26 |
|
/* Type of event object handle. */ |
|
27 |
|
#ifdef _WIN32 |
|
28 |
|
#include <windows.h> |
|
29 |
|
typedef HANDLE event_end_t; |
|
30 |
|
#else |
|
31 |
|
typedef int event_end_t; |
|
32 |
|
#endif |
|
33 |
|
|
|
34 |
|
/* Opaque event type. */ |
|
35 |
|
typedef struct event_t event_t; |
|
36 |
|
|
|
37 |
|
/* Allocates new event object in non-signaled state. Returns the event or NULL |
|
38 |
|
* on error. */ |
|
39 |
|
event_t * event_alloc(void); |
|
40 |
|
|
|
41 |
|
/* Frees the event. The parameter can be NULL. */ |
|
42 |
|
void event_free(event_t *event); |
|
43 |
|
|
|
44 |
|
/* Switches the event to the signaled state. Returns zero on success. */ |
|
45 |
|
int event_signal(event_t *event); |
|
46 |
|
|
|
47 |
|
/* Switches the event back to the non-signaled state. Should be called after |
|
48 |
|
* finding event in the signaled state. Returns zero on success. */ |
|
49 |
|
int event_reset(event_t *event); |
|
50 |
|
|
|
51 |
|
/* Retrieves value that can be used to wait until the event reaches signaled |
|
52 |
|
* state. */ |
|
53 |
|
event_end_t event_wait_end(const event_t *event); |
|
54 |
|
|
|
55 |
|
#endif /* VIFM__UTILS__EVENT_H__ */ |
|
56 |
|
|
|
57 |
|
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ |
|
58 |
|
/* vim: set cinoptions+=t0 : */ |
File src/utils/event_nix.c added (mode: 100644) (index 000000000..348f72184) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2024 xaizek. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
#include "event.h" |
|
20 |
|
|
|
21 |
|
#include <fcntl.h> /* F_GETFL F_SETFL O_NONBLOCK fcntl() */ |
|
22 |
|
#include <unistd.h> /* close() pipe() read() write() */ |
|
23 |
|
|
|
24 |
|
#include <stdlib.h> /* free() malloc() */ |
|
25 |
|
|
|
26 |
|
/* Event object data. */ |
|
27 |
|
struct event_t |
|
28 |
|
{ |
|
29 |
|
int r; /* Read end of the pipe. */ |
|
30 |
|
int w; /* Write end of the pipe. */ |
|
31 |
|
}; |
|
32 |
|
|
|
33 |
|
event_t * |
|
34 |
|
event_alloc(void) |
|
35 |
|
{ |
|
36 |
|
event_t *event = malloc(sizeof(*event)); |
|
37 |
|
if(event == NULL) |
|
38 |
|
{ |
|
39 |
|
return NULL; |
|
40 |
|
} |
|
41 |
|
|
|
42 |
|
int fds[2]; |
|
43 |
|
if(pipe(fds) != 0) |
|
44 |
|
{ |
|
45 |
|
free(event); |
|
46 |
|
return NULL; |
|
47 |
|
} |
|
48 |
|
|
|
49 |
|
event->r = fds[0]; |
|
50 |
|
event->w = fds[1]; |
|
51 |
|
|
|
52 |
|
/* Make reading from the pipe to not block. */ |
|
53 |
|
int flags = fcntl(event->r, F_GETFL, 0); |
|
54 |
|
if(flags == -1) |
|
55 |
|
{ |
|
56 |
|
event_free(event); |
|
57 |
|
return NULL; |
|
58 |
|
} |
|
59 |
|
if(fcntl(event->r, F_SETFL, flags | O_NONBLOCK) != 0) |
|
60 |
|
{ |
|
61 |
|
event_free(event); |
|
62 |
|
return NULL; |
|
63 |
|
} |
|
64 |
|
|
|
65 |
|
return event; |
|
66 |
|
} |
|
67 |
|
|
|
68 |
|
void |
|
69 |
|
event_free(event_t *event) |
|
70 |
|
{ |
|
71 |
|
if(event != NULL) |
|
72 |
|
{ |
|
73 |
|
close(event->r); |
|
74 |
|
close(event->w); |
|
75 |
|
free(event); |
|
76 |
|
} |
|
77 |
|
} |
|
78 |
|
|
|
79 |
|
int |
|
80 |
|
event_signal(event_t *event) |
|
81 |
|
{ |
|
82 |
|
char buf = '\0'; |
|
83 |
|
if(write(event->w, &buf, sizeof(buf)) != sizeof(buf)) |
|
84 |
|
{ |
|
85 |
|
return -1; |
|
86 |
|
} |
|
87 |
|
return 0; |
|
88 |
|
} |
|
89 |
|
|
|
90 |
|
int |
|
91 |
|
event_reset(event_t *event) |
|
92 |
|
{ |
|
93 |
|
char buf = '\0'; |
|
94 |
|
if(read(event->r, &buf, sizeof(buf)) != sizeof(buf)) |
|
95 |
|
{ |
|
96 |
|
/* Error if we couldn't read anything for whatever reason. */ |
|
97 |
|
return -1; |
|
98 |
|
} |
|
99 |
|
|
|
100 |
|
ssize_t n; |
|
101 |
|
while((n = read(event->r, &buf, sizeof(buf))) == sizeof(buf)) |
|
102 |
|
{ |
|
103 |
|
/* Keep reading. */ |
|
104 |
|
} |
|
105 |
|
/* Don't report an error on EOF (when nothing is read). */ |
|
106 |
|
return (n == 0 ? 0 : -1); |
|
107 |
|
} |
|
108 |
|
|
|
109 |
|
int |
|
110 |
|
event_wait_end(const event_t *event) |
|
111 |
|
{ |
|
112 |
|
return event->r; |
|
113 |
|
} |
|
114 |
|
|
|
115 |
|
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ |
|
116 |
|
/* vim: set cinoptions+=t0 : */ |
File src/utils/event_win.c copied from file src/compat/dtype.c (similarity 52%) (mode: 100644) (index 3247f4e9b..a27ff7d5f) |
1 |
1 |
/* vifm |
/* vifm |
2 |
|
* Copyright (C) 2016 xaizek. |
|
|
2 |
|
* Copyright (C) 2024 xaizek. |
3 |
3 |
* |
* |
4 |
4 |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
5 |
5 |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
|
16 |
16 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
17 |
17 |
*/ |
*/ |
18 |
18 |
|
|
19 |
|
#include "dtype.h" |
|
20 |
|
#include <dirent.h> /* dirent */ |
|
|
19 |
|
#include "event.h" |
21 |
20 |
|
|
22 |
|
#if !defined(HAVE_STRUCT_DIRENT_D_TYPE) || !HAVE_STRUCT_DIRENT_D_TYPE |
|
|
21 |
|
#include <windows.h> |
23 |
22 |
|
|
24 |
|
#include "os.h" |
|
|
23 |
|
#include <stdlib.h> /* free() malloc() */ |
25 |
24 |
|
|
26 |
|
unsigned char |
|
27 |
|
get_dirent_type(const struct dirent *dentry, const char path[]) |
|
|
25 |
|
/* Event object data. */ |
|
26 |
|
struct event_t |
28 |
27 |
{ |
{ |
29 |
|
struct stat st; |
|
|
28 |
|
HANDLE h; /* Handle to the event object. */ |
|
29 |
|
}; |
30 |
30 |
|
|
31 |
|
if(os_lstat(path, &st) != 0 || st.st_ino == 0) |
|
|
31 |
|
event_t * |
|
32 |
|
event_alloc(void) |
|
33 |
|
{ |
|
34 |
|
event_t *event = malloc(sizeof(*event)); |
|
35 |
|
if(event == NULL) |
|
36 |
|
{ |
|
37 |
|
return NULL; |
|
38 |
|
} |
|
39 |
|
|
|
40 |
|
event->h = CreateEvent(/*attrs=*/NULL, /*manual_reset=*/TRUE, |
|
41 |
|
/*initial_state=*/FALSE, /*name=*/NULL); |
|
42 |
|
|
|
43 |
|
if(event->h == NULL) |
32 |
44 |
{ |
{ |
33 |
|
return DT_UNKNOWN; |
|
|
45 |
|
free(event); |
|
46 |
|
return NULL; |
34 |
47 |
} |
} |
35 |
48 |
|
|
36 |
|
switch(st.st_mode & S_IFMT) |
|
|
49 |
|
return event; |
|
50 |
|
} |
|
51 |
|
|
|
52 |
|
void |
|
53 |
|
event_free(event_t *event) |
|
54 |
|
{ |
|
55 |
|
if(event != NULL) |
37 |
56 |
{ |
{ |
38 |
|
case S_IFBLK: return DT_BLK; |
|
39 |
|
case S_IFCHR: return DT_CHR; |
|
40 |
|
case S_IFDIR: return DT_DIR; |
|
41 |
|
case S_IFIFO: return DT_FIFO; |
|
42 |
|
case S_IFREG: return DT_REG; |
|
43 |
|
#ifndef _WIN32 |
|
44 |
|
case S_IFLNK: return DT_LNK; |
|
45 |
|
case S_IFSOCK: return DT_SOCK; |
|
46 |
|
#endif |
|
47 |
|
|
|
48 |
|
default: return DT_UNKNOWN; |
|
|
57 |
|
CloseHandle(event->h); |
|
58 |
|
free(event); |
49 |
59 |
} |
} |
50 |
60 |
} |
} |
51 |
61 |
|
|
52 |
|
#else |
|
|
62 |
|
int |
|
63 |
|
event_signal(event_t *event) |
|
64 |
|
{ |
|
65 |
|
return (SetEvent(event->h) ? 0 : -1); |
|
66 |
|
} |
53 |
67 |
|
|
54 |
|
unsigned char |
|
55 |
|
get_dirent_type(const struct dirent *dentry, const char path[]) |
|
|
68 |
|
int |
|
69 |
|
event_reset(event_t *event) |
56 |
70 |
{ |
{ |
57 |
|
return dentry->d_type; |
|
|
71 |
|
return (ResetEvent(event->h) ? 0 : -1); |
58 |
72 |
} |
} |
59 |
73 |
|
|
60 |
|
#endif |
|
|
74 |
|
HANDLE |
|
75 |
|
event_wait_end(const event_t *event) |
|
76 |
|
{ |
|
77 |
|
return event->h; |
|
78 |
|
} |
61 |
79 |
|
|
62 |
80 |
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ |
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ |
63 |
81 |
/* vim: set cinoptions+=t0 : */ |
/* vim: set cinoptions+=t0 : */ |