1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 /*
7  * File: fdcach.c
8  * Description:
9  *   This test verifies that the fd cache is working
10  *   correctly.
11  */
12 
13 #include "nspr.h"
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 
18 /*
19  * Define ORDER_PRESERVED if the implementation of PR_SetFDCacheSize
20  * preserves the ordering of the fd's when moving them between the
21  * cache.
22  */
23 #define ORDER_PRESERVED 1
24 
25 /*
26  * NUM_FDS must be <= FD_CACHE_SIZE.
27  */
28 #define FD_CACHE_SIZE 1024
29 #define NUM_FDS 20
30 
main(int argc,char ** argv)31 int main(int argc, char **argv)
32 {
33     int i;
34     PRFileDesc *fds[NUM_FDS];
35     PRFileDesc *savefds[NUM_FDS];
36     int numfds = sizeof(fds)/sizeof(fds[0]);
37 
38     PR_SetFDCacheSize(0, FD_CACHE_SIZE);
39 
40     /* Add some fd's to the fd cache. */
41     for (i = 0; i < numfds; i++) {
42         savefds[i] = PR_NewTCPSocket();
43         if (NULL == savefds[i]) {
44             fprintf(stderr, "PR_NewTCPSocket failed\n");
45             exit(1);
46         }
47     }
48     for (i = 0; i < numfds; i++) {
49         if (PR_Close(savefds[i]) == PR_FAILURE) {
50             fprintf(stderr, "PR_Close failed\n");
51             exit(1);
52         }
53     }
54 
55     /*
56      * Create some fd's.  These fd's should come from
57      * the fd cache.  Verify the FIFO ordering of the fd
58      * cache.
59      */
60     for (i = 0; i < numfds; i++) {
61         fds[i] = PR_NewTCPSocket();
62         if (NULL == fds[i]) {
63             fprintf(stderr, "PR_NewTCPSocket failed\n");
64             exit(1);
65         }
66         if (fds[i] != savefds[i]) {
67             fprintf(stderr, "fd cache malfunctioned\n");
68             exit(1);
69         }
70     }
71     /* Put the fd's back to the fd cache. */
72     for (i = 0; i < numfds; i++) {
73         if (PR_Close(savefds[i]) == PR_FAILURE) {
74             fprintf(stderr, "PR_Close failed\n");
75             exit(1);
76         }
77     }
78 
79     /* Switch to the fd cache. */
80     PR_SetFDCacheSize(0, FD_CACHE_SIZE);
81 
82     for (i = 0; i < numfds; i++) {
83         fds[i] = PR_NewTCPSocket();
84         if (NULL == fds[i]) {
85             fprintf(stderr, "PR_NewTCPSocket failed\n");
86             exit(1);
87         }
88 #ifdef ORDER_PRESERVED
89         if (fds[i] != savefds[i]) {
90             fprintf(stderr, "fd cache malfunctioned\n");
91             exit(1);
92         }
93 #else
94         savefds[i] = fds[i];
95 #endif
96     }
97     for (i = 0; i < numfds; i++) {
98         if (PR_Close(savefds[i]) == PR_FAILURE) {
99             fprintf(stderr, "PR_Close failed\n");
100             exit(1);
101         }
102     }
103 
104     for (i = 0; i < numfds; i++) {
105         fds[i] = PR_NewTCPSocket();
106         if (NULL == fds[i]) {
107             fprintf(stderr, "PR_NewTCPSocket failed\n");
108             exit(1);
109         }
110         if (fds[i] != savefds[i]) {
111             fprintf(stderr, "fd cache malfunctioned\n");
112             exit(1);
113         }
114     }
115     for (i = 0; i < numfds; i++) {
116         if (PR_Close(savefds[i]) == PR_FAILURE) {
117             fprintf(stderr, "PR_Close failed\n");
118             exit(1);
119         }
120     }
121 
122     PR_Cleanup();
123     printf("PASS\n");
124     return 0;
125 }
126