From: Michael D. Lowis Date: Thu, 22 Mar 2018 17:24:24 +0000 (-0400) Subject: major rework of syntax highlighter and job processing code. Incomplete checkpoint... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=d7de320183be3f21bd7e2fde29d4ba31e4c0ff73;p=projs%2Ftide.git major rework of syntax highlighter and job processing code. Incomplete checkpoint commit --- diff --git a/inc/edit.h b/inc/edit.h index 98d41cc..15c0a4f 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -219,16 +219,16 @@ typedef struct Job Job; typedef void (*jobfn_t)(Job* job); struct Job { + Job *next; int pid, fd; - void* data; - void (*writefn)(Job* job); - void (*readfn)(Job* job); + void *data; + void (*writefn)(Job *job); + void (*readfn)(Job *job); }; -bool exec_poll(int fd, int ms); -int exec_reap(void); -void exec_job(char** cmd, char* data, size_t ndata, View* dest); -int exec_spawn(char** cmd, int* in, int* out); +bool job_poll(int fd, int ms); +void job_create(char** cmd, jobfn_t readfn, jobfn_t writefn, void* data); +void job_start(char** cmd, char* data, size_t ndata, View* dest); /* Configuration Data *****************************************************************************/ diff --git a/lib/colors.c b/lib/colors.c index 651c15f..b7e82c9 100644 --- a/lib/colors.c +++ b/lib/colors.c @@ -14,12 +14,19 @@ static void write_chunk(Buf* buf, size_t beg, size_t end); static int read_byte(void); static int read_num(void); +static void writefn(Job* job) { +} + +static void readfn(Job* job) { +} + void colors_init(char* path) { if (Syntax) - exec_spawn((char*[]){ "tide-hl.rb", path, NULL }, &ChildIn, &ChildOut); + job_create((char*[]){ "tide-hl.rb", path, NULL }, readfn, writefn, 0); } SyntaxSpan* colors_scan(SyntaxSpan* spans, Buf* buf, size_t beg, size_t end) { +#if 0 SyntaxSpan* firstspan = spans; SyntaxSpan* currspan = spans; /* if the engine died, clear all highlights and quit */ @@ -44,9 +51,13 @@ SyntaxSpan* colors_scan(SyntaxSpan* spans, Buf* buf, size_t beg, size_t end) { DataBeg = DataEnd = Buffer; } return firstspan; +#else + return spans; +#endif } SyntaxSpan* colors_rewind(SyntaxSpan* spans, size_t first) { +#if 0 SyntaxSpan *curr = spans, *next = (spans ? spans->next : NULL); while (curr && curr->end > first) next = curr, curr = curr->prev; @@ -60,8 +71,12 @@ SyntaxSpan* colors_rewind(SyntaxSpan* spans, size_t first) { free(dead); } return curr; +#else + return spans; +#endif } +#if 0 static SyntaxSpan* mkspan(size_t beg, size_t end, size_t clr, SyntaxSpan* span) { SyntaxSpan* newspan = malloc(sizeof(SyntaxSpan)); newspan->beg = beg; @@ -115,3 +130,4 @@ static int read_num(void) { num = (num * 10) + (c - '0'); return num; } +#endif diff --git a/lib/job.c b/lib/job.c index 9e7cf16..f86e779 100644 --- a/lib/job.c +++ b/lib/job.c @@ -9,49 +9,86 @@ #include #include -#define MAX_JOBS 1024 +static void job_process(int fd, int events); +static int job_execute(char** cmd, int *fd, int *pid); +static void job_finish(Job* job); -static struct pollfd Jobs[MAX_JOBS]; +#define MAX_JOBS 256 -bool exec_poll(int fd, int ms) { +static struct pollfd JobFds[MAX_JOBS]; +static Job* JobList = NULL; + +bool job_poll(int fd, int ms) { int njobs = 0; + /* add the X11 connection if we have one */ if (fd > 0) { - Jobs[0].fd = fd; - Jobs[0].events = POLLIN; - Jobs[0].revents = 0; + JobFds[0].fd = fd; + JobFds[0].events = POLLIN; + JobFds[0].revents = 0; njobs = 1; } - - long ret = poll(Jobs, njobs, ms); - + /* Add jobs from the job list */ + for (Job *job = JobList; job && njobs < MAX_JOBS; job = job->next) { + JobFds[njobs].fd = job->fd; + JobFds[njobs].events = 0; + JobFds[njobs].revents = 0; + if (job->readfn) JobFds[njobs].events = POLLIN; + if (job->writefn) JobFds[njobs].events = POLLOUT; + if (JobFds[njobs].events) njobs++; + } + /* Poll until a job is ready, call the functions based on events */ + long ret = poll(JobFds, njobs, ms); + for (int i = 1; i < njobs; i++) + job_process(JobFds[i].fd, JobFds[i].revents); /* reap zombie processes */ for (int status; waitpid(-1, &status, WNOHANG) > 0;); - + // TODO: cleanup old jobs here... return (ret > 0); } -int exec_reap(void) { - return 0; +void job_create(char** cmd, jobfn_t readfn, jobfn_t writefn, void* data) { + int fd = -1, pid = -1; + if (job_execute(cmd, &fd, &pid) > 0) { + Job *job = calloc(1, sizeof(job)); + job->fd = fd; + job->pid = pid; + job->readfn = readfn; + job->writefn = writefn; + job->data = data; + job->next = JobList; + JobList = job; + } } -int exec_spawn(char** cmd, int* in, int* out) { - return -1; +void job_start(char** cmd, char* data, size_t ndata, View* dest) { + } -void exec_job(char** cmd, char* data, size_t ndata, View* dest) { +static void job_process(int fd, int events) { + Job* job = NULL; // Get job by fd + if (job->readfn && (events & POLLIN)) + job->readfn(job); + if (job->writefn && (events & POLLOUT)) + job->writefn(job); + if (!job->readfn && !job->writefn) + job_finish(job); +} +static void job_finish(Job* job) { + close(job->fd); + // delete job + // free(job); } -#if 0 -static int execute(char** cmd, Proc* proc) { +static int job_execute(char** cmd, int *fd, int *pid) { int fds[2]; /* create the sockets */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) return -1; /* create the process */ - if ((proc->pid = fork()) < 0) { - close(fds[0]), close(fds[1]), proc->fd = -1; - } else if (0 == proc->pid) { + if ((*pid = fork()) < 0) { + close(fds[0]), close(fds[1]), *fd = -1; + } else if (0 == *pid) { /* redirect child process's io to the pipes */ if ((dup2(fds[1], 0) < 0) || (dup2(fds[1], 1) < 0) || (dup2(fds[1], 2) < 0)) { perror("failed to pipe"); @@ -61,8 +98,7 @@ static int execute(char** cmd, Proc* proc) { close(fds[0]); exit(execvp(cmd[0], cmd)); } else { - close(fds[1]), proc->fd = fds[0]; + close(fds[1]), *fd = fds[0]; } - return proc->pid; + return *pid; } -#endif diff --git a/lib/win.c b/lib/win.c index 9e767cf..a3aa773 100644 --- a/lib/win.c +++ b/lib/win.c @@ -98,8 +98,7 @@ void win_save(char* path) { void win_loop(void) { x11_show(); while (x11_running()) { - bool pending = exec_poll(x11_connfd(), Timeout); - exec_reap(); + bool pending = job_poll(x11_connfd(), Timeout); int nevents = x11_events_queued(); if (update_focus() || pending || nevents) { x11_events_take(); diff --git a/lib/x11.c b/lib/x11.c index 7dc504c..8d7385f 100644 --- a/lib/x11.c +++ b/lib/x11.c @@ -210,8 +210,8 @@ void x11_finish(void) { if (Selections[CLIPBOARD].text) { char* text = Selections[CLIPBOARD].text; size_t len = strlen(text); - exec_job((char*[]){ "xcpd", NULL }, text, len, NULL); - while (exec_poll(-1, 100)); + job_start((char*[]){ "xcpd", NULL }, text, len, NULL); + while (job_poll(-1, 100)); } } diff --git a/tide.c b/tide.c index 7af97c1..ed7307f 100644 --- a/tide.c +++ b/tide.c @@ -77,13 +77,13 @@ static void cmd_exec(char* cmd) { /* execute the job */ if (op == '!') - free(input), exec_job(execcmd, NULL, 0, NULL); + free(input), job_start(execcmd, NULL, 0, NULL); else if (op == '>') - exec_job(execcmd, input, len, tags); + job_start(execcmd, input, len, tags); else if (op == '|' || op == ':') - exec_job(execcmd, input, len, edit); + job_start(execcmd, input, len, edit); else - exec_job(execcmd, input, len, (op != '<' ? curr : edit)); + job_start(execcmd, input, len, (op != '<' ? curr : edit)); } static void cmd_execwitharg(char* cmd, char* arg) {