Skip to content

Commit

Permalink
[core] make the per-process IPC sending non-blocking
Browse files Browse the repository at this point in the history
A process may get stuck (history showed us such real cases) and we do not want to have other processes getting blocked by trying to do an IPC to such procs (if they are stuck, they will not consume their IPC cmds, so the IPC sender will also block after some time, when the pipe's buffer is full).
So, better make the write pipe non-blocking, discard the current IPC cmd and avoid escalating the blocking over other procs.

(cherry picked from commit 62af720)
  • Loading branch information
bogdan-iancu committed Nov 8, 2021
1 parent 671cc25 commit babfb7d
Showing 1 changed file with 36 additions and 4 deletions.
40 changes: 36 additions & 4 deletions ipc.c
Expand Up @@ -98,7 +98,7 @@ int init_ipc(void)

int create_ipc_pipes( int proc_no )
{
int i;
int optval, i;

for( i=0 ; i<proc_no ; i++ ) {
if (pipe(pt[i].ipc_pipe_holder)<0) {
Expand All @@ -107,11 +107,39 @@ int create_ipc_pipes( int proc_no )
return -1;
}

/* make writing fd non-blocking */
optval = fcntl( pt[i].ipc_pipe_holder[1], F_GETFL);
if (optval == -1) {
LM_ERR("fcntl failed: (%d) %s\n", errno, strerror(errno));
return -1;
}

if (fcntl(pt[i].ipc_pipe_holder[1], F_SETFL, optval|O_NONBLOCK) == -1){
LM_ERR("set non-blocking write failed: (%d) %s\n",
errno, strerror(errno));
return -1;
}


if (pipe(pt[i].ipc_sync_pipe_holder)<0) {
LM_ERR("failed to create IPC sync pipe for process %d, err %d/%s\n",
i, errno, strerror(errno));
LM_ERR("failed to create IPC sync pipe for process %d, "
"err %d/%s\n", i, errno, strerror(errno));
return -1;
}

/* make writing fd non-blocking */
optval = fcntl( pt[i].ipc_sync_pipe_holder[1], F_GETFL);
if (optval == -1) {
LM_ERR("fcntl failed: (%d) %s\n", errno, strerror(errno));
return -1;
}

if (fcntl(pt[i].ipc_sync_pipe_holder[1], F_SETFL, optval|O_NONBLOCK) == -1){
LM_ERR("set non-blocking write failed: (%d) %s\n",
errno, strerror(errno));
return -1;
}

}
return 0;
}
Expand Down Expand Up @@ -167,7 +195,11 @@ static inline int __ipc_send_job(int fd, ipc_handler_type type,
job.payload2 = payload2;

again:
// TODO - should we do this non blocking and discard if we block ??
/* The per-proc IPC write fds are sent to non-blocking (to be sure we
* do not escalate into a global blocking if a single process got stuck.
* In such care the EAGAIN or EWOULDBLOCK will be thrown and we will
* handle as generic error, nothing special to do.
*/
n = write(fd, &job, sizeof(job) );
if (n<0) {
if (errno==EINTR)
Expand Down

0 comments on commit babfb7d

Please sign in to comment.