michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * File: fdcach.c michael@0: * Description: michael@0: * This test verifies that the fd cache and stack are working michael@0: * correctly. michael@0: */ michael@0: michael@0: #include "nspr.h" michael@0: michael@0: #include michael@0: #include michael@0: michael@0: /* michael@0: * Define ORDER_PRESERVED if the implementation of PR_SetFDCacheSize michael@0: * preserves the ordering of the fd's when moving them between the michael@0: * cache and the stack. michael@0: */ michael@0: #define ORDER_PRESERVED 1 michael@0: michael@0: /* michael@0: * NUM_FDS must be <= FD_CACHE_SIZE. michael@0: */ michael@0: #define FD_CACHE_SIZE 1024 michael@0: #define NUM_FDS 20 michael@0: michael@0: int main(int argc, char **argv) michael@0: { michael@0: int i; michael@0: PRFileDesc *fds[NUM_FDS]; michael@0: PRFileDesc *savefds[NUM_FDS]; michael@0: int numfds = sizeof(fds)/sizeof(fds[0]); michael@0: michael@0: /* michael@0: * Switch between cache and stack when they are empty. michael@0: * Then start with the fd cache. michael@0: */ michael@0: PR_SetFDCacheSize(0, FD_CACHE_SIZE); michael@0: PR_SetFDCacheSize(0, 0); michael@0: PR_SetFDCacheSize(0, FD_CACHE_SIZE); michael@0: michael@0: /* Add some fd's to the fd cache. */ michael@0: for (i = 0; i < numfds; i++) { michael@0: savefds[i] = PR_NewTCPSocket(); michael@0: if (NULL == savefds[i]) { michael@0: fprintf(stderr, "PR_NewTCPSocket failed\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: for (i = 0; i < numfds; i++) { michael@0: if (PR_Close(savefds[i]) == PR_FAILURE) { michael@0: fprintf(stderr, "PR_Close failed\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: michael@0: /* michael@0: * Create some fd's. These fd's should come from michael@0: * the fd cache. Verify the FIFO ordering of the fd michael@0: * cache. michael@0: */ michael@0: for (i = 0; i < numfds; i++) { michael@0: fds[i] = PR_NewTCPSocket(); michael@0: if (NULL == fds[i]) { michael@0: fprintf(stderr, "PR_NewTCPSocket failed\n"); michael@0: exit(1); michael@0: } michael@0: if (fds[i] != savefds[i]) { michael@0: fprintf(stderr, "fd cache malfunctioned\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: /* Put the fd's back to the fd cache. */ michael@0: for (i = 0; i < numfds; i++) { michael@0: if (PR_Close(savefds[i]) == PR_FAILURE) { michael@0: fprintf(stderr, "PR_Close failed\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: michael@0: /* Switch to the fd stack. */ michael@0: PR_SetFDCacheSize(0, 0); michael@0: michael@0: /* michael@0: * Create some fd's. These fd's should come from michael@0: * the fd stack. michael@0: */ michael@0: for (i = 0; i < numfds; i++) { michael@0: fds[i] = PR_NewTCPSocket(); michael@0: if (NULL == fds[i]) { michael@0: fprintf(stderr, "PR_NewTCPSocket failed\n"); michael@0: exit(1); michael@0: } michael@0: #ifdef ORDER_PRESERVED michael@0: if (fds[i] != savefds[numfds-1-i]) { michael@0: fprintf(stderr, "fd stack malfunctioned\n"); michael@0: exit(1); michael@0: } michael@0: #else michael@0: savefds[numfds-1-i] = fds[i]; michael@0: #endif michael@0: } michael@0: /* Put the fd's back to the fd stack. */ michael@0: for (i = 0; i < numfds; i++) { michael@0: if (PR_Close(savefds[i]) == PR_FAILURE) { michael@0: fprintf(stderr, "PR_Close failed\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: michael@0: /* michael@0: * Now create some fd's and verify the LIFO ordering of michael@0: * the fd stack. michael@0: */ michael@0: for (i = 0; i < numfds; i++) { michael@0: fds[i] = PR_NewTCPSocket(); michael@0: if (NULL == fds[i]) { michael@0: fprintf(stderr, "PR_NewTCPSocket failed\n"); michael@0: exit(1); michael@0: } michael@0: if (fds[i] != savefds[numfds-1-i]) { michael@0: fprintf(stderr, "fd stack malfunctioned\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: /* Put the fd's back to the fd stack. */ michael@0: for (i = 0; i < numfds; i++) { michael@0: if (PR_Close(savefds[i]) == PR_FAILURE) { michael@0: fprintf(stderr, "PR_Close failed\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: michael@0: /* Switch to the fd cache. */ michael@0: PR_SetFDCacheSize(0, FD_CACHE_SIZE); michael@0: michael@0: for (i = 0; i < numfds; i++) { michael@0: fds[i] = PR_NewTCPSocket(); michael@0: if (NULL == fds[i]) { michael@0: fprintf(stderr, "PR_NewTCPSocket failed\n"); michael@0: exit(1); michael@0: } michael@0: #ifdef ORDER_PRESERVED michael@0: if (fds[i] != savefds[i]) { michael@0: fprintf(stderr, "fd cache malfunctioned\n"); michael@0: exit(1); michael@0: } michael@0: #else michael@0: savefds[i] = fds[i]; michael@0: #endif michael@0: } michael@0: for (i = 0; i < numfds; i++) { michael@0: if (PR_Close(savefds[i]) == PR_FAILURE) { michael@0: fprintf(stderr, "PR_Close failed\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: michael@0: for (i = 0; i < numfds; i++) { michael@0: fds[i] = PR_NewTCPSocket(); michael@0: if (NULL == fds[i]) { michael@0: fprintf(stderr, "PR_NewTCPSocket failed\n"); michael@0: exit(1); michael@0: } michael@0: if (fds[i] != savefds[i]) { michael@0: fprintf(stderr, "fd cache malfunctioned\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: for (i = 0; i < numfds; i++) { michael@0: if (PR_Close(savefds[i]) == PR_FAILURE) { michael@0: fprintf(stderr, "PR_Close failed\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: michael@0: /* Switch to the fd stack. */ michael@0: PR_SetFDCacheSize(0, 0); michael@0: michael@0: for (i = 0; i < numfds; i++) { michael@0: fds[i] = PR_NewTCPSocket(); michael@0: if (NULL == fds[i]) { michael@0: fprintf(stderr, "PR_NewTCPSocket failed\n"); michael@0: exit(1); michael@0: } michael@0: #ifdef ORDER_PRESERVED michael@0: if (fds[i] != savefds[numfds-1-i]) { michael@0: fprintf(stderr, "fd stack malfunctioned\n"); michael@0: exit(1); michael@0: } michael@0: #else michael@0: savefds[numfds-1-i]; michael@0: #endif michael@0: } michael@0: for (i = 0; i < numfds; i++) { michael@0: if (PR_Close(savefds[i]) == PR_FAILURE) { michael@0: fprintf(stderr, "PR_Close failed\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: michael@0: for (i = 0; i < numfds; i++) { michael@0: fds[i] = PR_NewTCPSocket(); michael@0: if (NULL == fds[i]) { michael@0: fprintf(stderr, "PR_NewTCPSocket failed\n"); michael@0: exit(1); michael@0: } michael@0: if (fds[i] != savefds[numfds-1-i]) { michael@0: fprintf(stderr, "fd stack malfunctioned\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: for (i = 0; i < numfds; i++) { michael@0: if (PR_Close(savefds[i]) == PR_FAILURE) { michael@0: fprintf(stderr, "PR_Close failed\n"); michael@0: exit(1); michael@0: } michael@0: } michael@0: michael@0: PR_Cleanup(); michael@0: printf("PASS\n"); michael@0: return 0; michael@0: }