According to my knowledge, I think if I only need to perform reading operation on one single fd, IO multiplexing like select/poll will not help on performance, it even causes more overhead than just reading fd blockingly.
But the linux auditd project however use select on one single reading socket. Could someone explain what the meaning of it?
The auditd code alse use libev on 1 socket/ 1 pipe and 5 signals. Is it better to use blocking read if I only care about the main netlink socket?
I think possible scenarios may be a listening udp receiver socket etc.
Code block is attached for convenience. Thanks in advance!
925 static int get_reply(int fd, struct audit_reply *rep, int seq)
926 {
927 int rc, i;
928 int timeout = 30; /* tenths of seconds */
929
930 for (i = 0; i < timeout; i++) {
931 struct timeval t;
932 fd_set read_mask;
933
934 t.tv_sec = 0;
935 t.tv_usec = 100000; /* .1 second */
936 FD_ZERO(&read_mask);
937 FD_SET(fd, &read_mask);
938 do {
939 rc = select(fd+1, &read_mask, NULL, NULL, &t);
940 } while (rc < 0 && errno == EINTR);
941 rc = audit_get_reply(fd, rep,
942 GET_REPLY_NONBLOCKING, 0);
943 if (rc > 0) {
944 /* Don't make decisions based on wrong packet */
945 if (rep->nlh->nlmsg_seq != seq)
946 continue;
947
948 /* If its not what we are expecting, keep looping */
949 if (rep->type == AUDIT_SIGNAL_INFO)
950 return 1;
951
952 /* If we get done or error, break out */
953 if (rep->type == NLMSG_DONE || rep->type == NLMSG_ERROR)
954 break;
955 }
956 }
957 return -1;
958 }
The performance would likely be variable depending on the platform (in this case Linux) but it shouldn't be quicker.
It seems the main reason the code is using select
is for its timeout abilities. It allows a read-with-timeout without actually modifying the timeout (SO_SNDTIMEO
, SO_RCVTIMEO
) of the socket [or if the socket at all even supports timeouts].