Last active
June 22, 2017 11:25
-
-
Save FreeSlave/c97120ebefa01f63f34bdeb202a7d26f to your computer and use it in GitHub Desktop.
EINTR test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import core.sys.posix.unistd; | |
| import core.sys.posix.sys.types; | |
| import core.sys.posix.sys.stat; | |
| import core.sys.posix.sys.wait; | |
| import core.sys.posix.fcntl; | |
| import core.sys.posix.signal; | |
| import core.stdc.stdio; | |
| import core.stdc.string; | |
| import core.stdc.stdlib; | |
| import core.stdc.errno; | |
| import std.getopt; | |
| import core.stdc.errno; | |
| import core.sys.posix.unistd; | |
| import std.traits; | |
| template deintr(alias func) | |
| if (isFunction!func && isIntegral!(ReturnType!func) && | |
| isSigned!(ReturnType!func) && functionLinkage!func == "C") | |
| { | |
| ReturnType!func deintr(Args...)(Parameters!func args, Args varArgs) | |
| { | |
| ReturnType!func result; | |
| do | |
| { | |
| result = func(args, varArgs); | |
| } | |
| while (result == -1 && .errno == EINTR); | |
| return result; | |
| } | |
| } | |
| static long numberOfTries = 1024*1024*10; | |
| extern(C) void signalHandler(int signalNumber) | |
| { | |
| } | |
| void checkError(int result, const char* where) | |
| { | |
| if (result == -1) { | |
| if (errno == EINTR) { | |
| perror(where); | |
| } else { | |
| perror("error"); | |
| } | |
| } | |
| } | |
| void consume(int readFd) | |
| { | |
| int i; | |
| long sum = 0; | |
| for(i=0; i<numberOfTries; ++i) { | |
| char[6] buf; | |
| while(1) { | |
| long result = read(readFd, buf.ptr, buf.length); | |
| if (result == -1) { | |
| if (errno == EINTR) { | |
| perror("read"); | |
| } else { | |
| perror("read"); | |
| break; | |
| } | |
| } else { | |
| sum += result; | |
| break; | |
| } | |
| } | |
| } | |
| printf("read: %d\n", sum); | |
| } | |
| void produce(int writeFd) | |
| { | |
| int i; | |
| long sum = 0; | |
| for(i=0; i<numberOfTries; ++i) { | |
| while(1) { | |
| long result = write(writeFd, "Hello\n".ptr, 6); | |
| if (result == -1) { | |
| if (errno == EINTR) { | |
| perror("write"); | |
| } else { | |
| perror("write"); | |
| break; | |
| } | |
| } else { | |
| sum += result; | |
| break; | |
| } | |
| } | |
| } | |
| printf("write: %d\n", sum); | |
| } | |
| pid_t forkConsumer(int* pipefds) | |
| { | |
| pid_t consumerPid = fork(); | |
| if (consumerPid == 0) { | |
| close(pipefds[1]); | |
| consume(pipefds[0]); | |
| close(pipefds[0]); | |
| exit(0); | |
| return 0; | |
| } else { | |
| return consumerPid; | |
| } | |
| } | |
| pid_t forkProducer(int* pipefds) | |
| { | |
| pid_t producerPid = fork(); | |
| if (producerPid == 0) { | |
| close(pipefds[0]); | |
| produce(pipefds[1]); | |
| close(pipefds[1]); | |
| exit(0); | |
| return 0; | |
| } else { | |
| return producerPid; | |
| } | |
| } | |
| int testProcesses(int* pipefds) | |
| { | |
| pid_t consumerPid = forkConsumer(pipefds); | |
| if (consumerPid == -1) { | |
| perror("fork consumer"); | |
| return 1; | |
| } | |
| pid_t producerPid = forkProducer(pipefds); | |
| if (producerPid == -1) { | |
| kill(consumerPid, SIGKILL); | |
| perror("fork producer"); | |
| return 1; | |
| } | |
| int i; | |
| for(i=0; i<numberOfTries; ++i) { | |
| kill(consumerPid, SIGINT); | |
| kill(producerPid, SIGINT); | |
| } | |
| int result; | |
| waitpid(producerPid, &result, 0); | |
| waitpid(consumerPid, &result, 0); | |
| return 0; | |
| } | |
| int main(string[] args) | |
| { | |
| getopt(args, "count", &numberOfTries); | |
| sigaction_t signalAction; | |
| memset(&signalAction, 0, sigaction_t.sizeof); | |
| signalAction.sa_handler = &signalHandler; | |
| sigaction(SIGINT, &signalAction, null); | |
| int[2] pipefds; | |
| if (pipe(pipefds) != 0) { | |
| perror("pipe"); | |
| exit(-1); | |
| } | |
| int result = testProcesses(pipefds.ptr); | |
| close(pipefds[0]); | |
| close(pipefds[1]); | |
| return result; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment