I'm trying to create a piped multithreaded, multiprocess program where the parent process will create a thread that will read from a pipe from a sending child and then write to another pipe to the target child. But when the sending child process invokes piped write() to the parent process, the parent process won't read; it continues to block.
Pipe creation and the parent process creating the thread
int value1 = pipe(to_parent[index]);
int value2 = pipe(from_parent[index]);
if(value1 == -1) {
perror("pipe");
continue;
}
if(value2 == -1) {
perror("pipe");
continue;
}
/* fork for every connection to the server*/
int pid = fork();
/*go back to the beginning of loop if fork fails*/
if(pid == -1) {
perror("fork failed");
continue;
}
/* parent process will go back to the beginning of the loop */
if(pid != 0) {
close(from_parent[index][0]);
close(to_parent[index][1]);
pthread_create(&parent_listen_to_child[index], NULL, listen_to_child, &index);
continue;
}
/*PIPE
CHILD => PARENT*/
void * listen_to_child(void * ptr) {
int index = *(int*)ptr;
int index_to_kill;
printf("listen_to_child\n");
read(to_parent[index][0], &index_to_kill, sizeof(int));
printf("talk to child\n");
write(from_parent[index_to_kill][1], &index, sizeof(int));
}
Child processes create the thread that reads from parent through pipe and a thread which would soon write to the parent through the pipe
void respond(int index) {
char buffer[MAX];
int client_socket = clients[index].socket;
char name[MAX_NAME_SIZE];
strcpy(name, get_name(client_socket));
strcpy(clients[index].name, name);
printf("%s has connected to the server\n", name);
print_names();
printf("hello\n");
pthread_create(&command_processor, NULL, receive_command, &index);
/* close pipe ends in child*/
close(from_parent[index][1]);
close(to_parent[index][0]);
pthread_create(&child_listen_to_parent, NULL, listen_to_parent, &index);
pthread_join(child_listen_to_parent, NULL);
pthread_join(command_processor, NULL);
}
/* PIPE
PARENT => CHILD TO CANCEL*/
void * listen_to_parent(void * ptr) {
int index = *(int*)ptr;
int tattle;
printf("listen_to_parent\n");
read(from_parent[index][0], &tattle, sizeof(int));
printf("cancel %s\n", clients[index].name);
pthread_cancel(command_processor);
}
Where the write to the parent process from sending child is invoked
void send_talk(client sender, client target) {
printf("sender: %s\ntarget: %s\n", sender.name, target.name);
int sender_index = get_index(sender.socket);
int target_index = get_index(target.socket);
int write_value;
if(( write_value = write(to_parent[sender_index][1], &target_index, sizeof(int))) != -1) {
printf("write successful: wrote %d bytes\n", write_value);
}
else {
printf("write unsuccessful\n");
}
}