mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-20 04:56:32 +00:00
Add full epoll_pwait
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
9484d35730
commit
07caaa5b3f
@ -14,6 +14,7 @@ TEST_APPS := \
|
||||
capability \
|
||||
clone3 \
|
||||
cpu_affinity \
|
||||
epoll \
|
||||
eventfd2 \
|
||||
execve \
|
||||
file_io \
|
||||
|
5
regression/apps/epoll/Makefile
Normal file
5
regression/apps/epoll/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
include ../test_common.mk
|
||||
|
||||
EXTRA_C_FLAGS :=
|
111
regression/apps/epoll/epoll_pwait.c
Normal file
111
regression/apps/epoll/epoll_pwait.c
Normal file
@ -0,0 +1,111 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
|
||||
// Signal handler for SIGUSR1
|
||||
static void handle_sigusr1(int sig)
|
||||
{
|
||||
write(STDOUT_FILENO, "SIGUSR1 handled\n", 16);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int pipefd[2]; // Array to store pipe file descriptors
|
||||
pid_t cpid; // Child process ID
|
||||
char buf[1024]; // Read buffer
|
||||
struct epoll_event ev, events[1];
|
||||
int epfd, nfds;
|
||||
|
||||
// Create a pipe
|
||||
if (pipe(pipefd) == -1) {
|
||||
perror("pipe error");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Create epoll instance
|
||||
if ((epfd = epoll_create1(0)) == -1) {
|
||||
perror("epoll_create1 error");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Fork to create child process
|
||||
cpid = fork();
|
||||
if (cpid == -1) {
|
||||
perror("fork error");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (cpid == 0) { // Child process
|
||||
close(pipefd[0]); // Child closes read end of the pipe
|
||||
|
||||
sleep(3); // Sleep for several seconds to provide a time window to send SIGUSR1
|
||||
|
||||
const char *message = "Message from child process\n";
|
||||
write(pipefd[1], message,
|
||||
strlen(message)); // Write a string to the pipe
|
||||
close(pipefd[1]); // Close write end of the pipe
|
||||
_exit(EXIT_SUCCESS);
|
||||
} else {
|
||||
// Parent process
|
||||
struct sigaction sa;
|
||||
sigset_t sigset;
|
||||
|
||||
// Setup signal handler for SIGUSR1
|
||||
sa.sa_handler = handle_sigusr1;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
if (sigaction(SIGUSR1, &sa, NULL) == -1) {
|
||||
perror("sigaction error");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Prepare the signal set to block SIGUSR1
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGUSR1);
|
||||
|
||||
close(pipefd[1]); // Parent closes write end of the pipe
|
||||
|
||||
// Set up epoll to listen for events
|
||||
ev.events = EPOLLIN; // Listen for input events
|
||||
ev.data.fd = pipefd[0];
|
||||
if (epoll_ctl(epfd, EPOLL_CTL_ADD, pipefd[0], &ev) == -1) {
|
||||
perror("epoll_ctl error");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Wait for events to occur, blocking SIGUSR1
|
||||
printf("Waiting for event on pipe, SIGUSR1 is blocked...\n");
|
||||
nfds = epoll_pwait(epfd, events, 1, -1, &sigset);
|
||||
if (nfds == -1) {
|
||||
perror("epoll_pwait error");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// If we get here, epoll_pwait was successful
|
||||
printf("epoll_pwait returned successfully.\n");
|
||||
if (events[0].data.fd == pipefd[0]) {
|
||||
// Read data
|
||||
ssize_t count = read(pipefd[0], buf, sizeof(buf) - 1);
|
||||
if (count > 0) {
|
||||
buf[count] =
|
||||
'\0'; // Ensure string is null-terminated
|
||||
printf("Received data: %s",
|
||||
buf); // Output the entire string
|
||||
}
|
||||
}
|
||||
|
||||
close(pipefd[0]); // Close read end of the pipe
|
||||
close(epfd); // Close the epoll file descriptor
|
||||
}
|
||||
|
||||
// Wait for the child process to complete
|
||||
wait(NULL);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
95
regression/apps/epoll/epoll_wait.c
Normal file
95
regression/apps/epoll/epoll_wait.c
Normal file
@ -0,0 +1,95 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int pipefd[2]; // Array to store pipe file descriptors
|
||||
pid_t cpid; // Child process ID
|
||||
char buf[1024]; // Read buffer
|
||||
struct epoll_event ev, events[1];
|
||||
int epfd, nfds;
|
||||
|
||||
// Create a pipe
|
||||
if (pipe(pipefd) == -1) {
|
||||
perror("pipe error");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Create epoll instance
|
||||
if ((epfd = epoll_create1(0)) == -1) {
|
||||
perror("epoll_create1 error");
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Fork to create child process
|
||||
cpid = fork();
|
||||
if (cpid == -1) {
|
||||
perror("fork error");
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
close(epfd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (cpid == 0) { // Child process
|
||||
close(pipefd[0]); // Child closes read end of the pipe
|
||||
const char *message = "Hello, world!\n";
|
||||
write(pipefd[1], message,
|
||||
strlen(message)); // Write a string to the pipe
|
||||
close(pipefd[1]); // Close write end of the pipe
|
||||
_exit(EXIT_SUCCESS);
|
||||
} else { // Parent process
|
||||
close(pipefd[1]); // Parent closes write end of the pipe
|
||||
|
||||
// Set up epoll to listen for events
|
||||
ev.events = EPOLLIN; // Listen for input events
|
||||
ev.data.fd = pipefd[0];
|
||||
if (epoll_ctl(epfd, EPOLL_CTL_ADD, pipefd[0], &ev) == -1) {
|
||||
perror("epoll_ctl error");
|
||||
close(pipefd[0]);
|
||||
close(epfd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Wait for events to occur
|
||||
printf("Waiting for event on pipe...\n");
|
||||
nfds = epoll_wait(epfd, events, 1, -1);
|
||||
if (nfds == -1) {
|
||||
perror("epoll_wait error");
|
||||
close(pipefd[0]);
|
||||
close(epfd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// If we get here, epoll_wait was successful
|
||||
printf("epoll_wait returned successfully.\n");
|
||||
if (events[0].data.fd == pipefd[0]) {
|
||||
// Read data
|
||||
ssize_t count = read(pipefd[0], buf, sizeof(buf) - 1);
|
||||
if (count > 0) {
|
||||
buf[count] =
|
||||
'\0'; // Ensure string is null-terminated
|
||||
printf("Received data: %s",
|
||||
buf); // Output the entire string
|
||||
} else {
|
||||
perror("read error");
|
||||
}
|
||||
}
|
||||
|
||||
close(pipefd[0]); // Close read end of the pipe
|
||||
close(epfd); // Close the epoll file descriptor
|
||||
}
|
||||
|
||||
// Wait for the child process to complete
|
||||
wait(NULL);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -11,5 +11,6 @@ cd ${SCRIPT_DIR}
|
||||
./ext2.sh
|
||||
./process.sh
|
||||
./network.sh
|
||||
./test_epoll_pwait.sh
|
||||
|
||||
echo "All regression tests passed."
|
||||
|
31
regression/apps/scripts/test_epoll_pwait.sh
Executable file
31
regression/apps/scripts/test_epoll_pwait.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
set -e
|
||||
|
||||
EPOLLTEST_DIR=/regression/epoll
|
||||
cd ${EPOLLTEST_DIR}
|
||||
|
||||
echo "Start epoll_pwait test......"
|
||||
|
||||
# Step 2: Run epoll_pwait in the background
|
||||
./epoll_pwait &
|
||||
EPOLL_PID=$!
|
||||
|
||||
echo "epoll_pwait PID: $EPOLL_PID"
|
||||
|
||||
# Step 3: Wait for 1 seconds to let epoll_pwait initialize and block SIGUSR1
|
||||
sleep 1
|
||||
|
||||
# Step 4: Send SIGUSR1 to epoll_pwait
|
||||
kill -USR1 $EPOLL_PID
|
||||
echo "Sent SIGUSR1 to PID $EPOLL_PID"
|
||||
|
||||
# Optional: Wait a bit more to see the output if the process is still running
|
||||
sleep 3
|
||||
|
||||
# You can also wait till the subprocess epoll_pwait completely finishes
|
||||
# wait $EPOLL_PID
|
||||
|
||||
echo "Test completed."
|
@ -1,9 +1,4 @@
|
||||
EpollTest.AllWritable
|
||||
EpollTest.LastReadable
|
||||
EpollTest.LastNonWritable
|
||||
EpollTest.Timeout_NoRandomSave
|
||||
EpollTest.WaitThenUnblock
|
||||
EpollTest.UnblockWithSignal
|
||||
EpollTest.TimeoutNoFds
|
||||
EpollTest.UnblockWithNewFD
|
||||
EpollTest.Oneshot
|
||||
|
Reference in New Issue
Block a user