Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: =?UTF-8?Q?Arne_Vajh=C3=B8j?= Newsgroups: comp.os.vms Subject: Re: Apache + mod_php performance Date: Mon, 7 Oct 2024 16:07:25 -0400 Organization: A noiseless patient Spider Lines: 294 Message-ID: References: <20241006181231.0000370b@yahoo.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Mon, 07 Oct 2024 22:07:25 +0200 (CEST) Injection-Info: dont-email.me; posting-host="770b7fe61781a117db0c3db1803d8bb4"; logging-data="1801655"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18upe066CQZvvvYzPWDfH/6u0Gm5T8A6ts=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:t/ZL23qguuKhdZsIu+qH73U4hQ0= Content-Language: en-US In-Reply-To: Bytes: 7984 On 10/7/2024 11:52 AM, Dan Cross wrote: > // Demonstration of a listener process that accepts > // incoming TCP connections and passes them to a > // worker process over Unix domain sockets. > // > // Dan Cross > > #include > #include > #include > #include > > #include > #include > #include > #include > #include > > // Sends a file descripter, `fd`, over a Unix domain socket `sd` > // via the 4.4BSD access rights passing mechanism. > // > // Returns 1 on success, -1 on failure. > int > sendfd(int sd, int fd) > { > struct msghdr mh; > struct iovec iv; > struct cmsghdr *ptr; > size_t len; > int ret; > char dummy; > > // Construct the control message header. Note this is > // malloc'ed to ensure proper alignment. > len = CMSG_SPACE(sizeof(int)); > ptr = malloc(len); > if (ptr == NULL) > return -1; > memset(ptr, 0, len); > ptr->cmsg_len = len; > ptr->cmsg_level = SOL_SOCKET; > ptr->cmsg_type = SCM_RIGHTS; > memcpy(CMSG_DATA(ptr), &fd, sizeof(int)); > > // We send a single byte of dummy data in case the > // implementation does not pass control data with an > // otherwise empty data transfer. > dummy = 0; > memset(&iv, 0, sizeof(iv)); > iv.iov_base = &dummy; > iv.iov_len = 1; > > // Construct the message header. Points to the dummy > // data and the control message header. > memset(&mh, 0, sizeof(mh)); > mh.msg_name = NULL; > mh.msg_namelen = 0; > mh.msg_iov = &iv; > mh.msg_iovlen = 1; > mh.msg_control = (caddr_t)ptr; > mh.msg_controllen = len; > mh.msg_flags = 0; > > // Loop in case there's no room in the kernel buffer > // to send. Cf.Stevens et al. > do { > ret = sendmsg(sd, &mh, 0); > } while (ret == 0); > free(ptr); > > return ret; > } > > // Receives a file descriptor over the Unix domain socket `sd` > // and store it into `*fdp` on success. > // > // Returns 1 on success, 0 on EOF, -1 on error. > int > recvfd(int sd, int *fdp) > { > struct msghdr mh; > struct iovec iv; > struct cmsghdr *ptr; > size_t len; > int ret; > char dummy; > > if (fdp == NULL) > return -1; > > // Allocate space for the control message. > len = CMSG_SPACE(sizeof(int)); > ptr = malloc(len); > if (ptr == NULL) > return -1; > > // Fill in an iovec to receive one byte of dummy data. > // Required on some systems that do not pass control > // messages on empty data transfers. > memset(&iv, 0, sizeof(iv)); > iv.iov_base = &dummy; > iv.iov_len = 1; > > // Fill in the msghdr structure. `recvmsg(2)` will > // update it. > memset(&mh, 0, sizeof(mh)); > mh.msg_name = NULL; > mh.msg_namelen = 0; > mh.msg_iov = &iv; > mh.msg_iovlen = 1; > mh.msg_control = ptr; > mh.msg_controllen = len; > mh.msg_flags = 0; > > ret = recvmsg(sd, &mh, 0); > if (ret <= 0) { > free(ptr); > return ret; > } > if (mh.msg_flags != 0) { > free(ptr); > return -1; > } > memcpy(fdp, CMSG_DATA(ptr), sizeof(int)); > free(ptr); > > return 1; > } > > void > dispatcher(int sdworker, int port) > { > int sd, nsd; > struct sockaddr_in sa; > struct sockaddr_in client; > socklen_t clientlen; > > sd = socket(AF_INET, SOCK_STREAM, 0); > if (sd < 0) { > perror("socket"); > close(sdworker); > exit(EXIT_FAILURE); > } > memset(&sa, 0, sizeof sa); > sa.sin_family = AF_INET; > sa.sin_port = htons((unsigned short)port); > sa.sin_addr.s_addr = htonl(INADDR_ANY); > if (bind(sd, (struct sockaddr *)&sa, sizeof sa) < 0) { > perror("bind"); > close(sdworker); > close(sd); > exit(EXIT_FAILURE); > } > if (listen(sd, 255) < 0) { > perror("listen"); > close(sdworker); > close(sd); > exit(EXIT_FAILURE); > } > > memset(&client, 0, sizeof client); > clientlen = sizeof client; > while ((nsd = accept(sd, (struct sockaddr *)&client, &clientlen)) >= 0) { > if (sendfd(sdworker, nsd) < 0) { > perror("sendfd"); > close(sdworker); > close(nsd); > close(sd); > exit(EXIT_FAILURE); > } > close(nsd); > } > } > > static void > echo(int sd) > { ========== REMAINDER OF ARTICLE TRUNCATED ==========