Fri, 16 Jan 2015 04:50:19 +0100
Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32
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/. */
6 /*
7 * File: fdcach.c
8 * Description:
9 * This test verifies that the fd cache and stack are working
10 * correctly.
11 */
13 #include "nspr.h"
15 #include <stdio.h>
16 #include <stdlib.h>
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 and the stack.
22 */
23 #define ORDER_PRESERVED 1
25 /*
26 * NUM_FDS must be <= FD_CACHE_SIZE.
27 */
28 #define FD_CACHE_SIZE 1024
29 #define NUM_FDS 20
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]);
38 /*
39 * Switch between cache and stack when they are empty.
40 * Then start with the fd cache.
41 */
42 PR_SetFDCacheSize(0, FD_CACHE_SIZE);
43 PR_SetFDCacheSize(0, 0);
44 PR_SetFDCacheSize(0, FD_CACHE_SIZE);
46 /* Add some fd's to the fd cache. */
47 for (i = 0; i < numfds; i++) {
48 savefds[i] = PR_NewTCPSocket();
49 if (NULL == savefds[i]) {
50 fprintf(stderr, "PR_NewTCPSocket failed\n");
51 exit(1);
52 }
53 }
54 for (i = 0; i < numfds; i++) {
55 if (PR_Close(savefds[i]) == PR_FAILURE) {
56 fprintf(stderr, "PR_Close failed\n");
57 exit(1);
58 }
59 }
61 /*
62 * Create some fd's. These fd's should come from
63 * the fd cache. Verify the FIFO ordering of the fd
64 * cache.
65 */
66 for (i = 0; i < numfds; i++) {
67 fds[i] = PR_NewTCPSocket();
68 if (NULL == fds[i]) {
69 fprintf(stderr, "PR_NewTCPSocket failed\n");
70 exit(1);
71 }
72 if (fds[i] != savefds[i]) {
73 fprintf(stderr, "fd cache malfunctioned\n");
74 exit(1);
75 }
76 }
77 /* Put the fd's back to the fd cache. */
78 for (i = 0; i < numfds; i++) {
79 if (PR_Close(savefds[i]) == PR_FAILURE) {
80 fprintf(stderr, "PR_Close failed\n");
81 exit(1);
82 }
83 }
85 /* Switch to the fd stack. */
86 PR_SetFDCacheSize(0, 0);
88 /*
89 * Create some fd's. These fd's should come from
90 * the fd stack.
91 */
92 for (i = 0; i < numfds; i++) {
93 fds[i] = PR_NewTCPSocket();
94 if (NULL == fds[i]) {
95 fprintf(stderr, "PR_NewTCPSocket failed\n");
96 exit(1);
97 }
98 #ifdef ORDER_PRESERVED
99 if (fds[i] != savefds[numfds-1-i]) {
100 fprintf(stderr, "fd stack malfunctioned\n");
101 exit(1);
102 }
103 #else
104 savefds[numfds-1-i] = fds[i];
105 #endif
106 }
107 /* Put the fd's back to the fd stack. */
108 for (i = 0; i < numfds; i++) {
109 if (PR_Close(savefds[i]) == PR_FAILURE) {
110 fprintf(stderr, "PR_Close failed\n");
111 exit(1);
112 }
113 }
115 /*
116 * Now create some fd's and verify the LIFO ordering of
117 * the fd stack.
118 */
119 for (i = 0; i < numfds; i++) {
120 fds[i] = PR_NewTCPSocket();
121 if (NULL == fds[i]) {
122 fprintf(stderr, "PR_NewTCPSocket failed\n");
123 exit(1);
124 }
125 if (fds[i] != savefds[numfds-1-i]) {
126 fprintf(stderr, "fd stack malfunctioned\n");
127 exit(1);
128 }
129 }
130 /* Put the fd's back to the fd stack. */
131 for (i = 0; i < numfds; i++) {
132 if (PR_Close(savefds[i]) == PR_FAILURE) {
133 fprintf(stderr, "PR_Close failed\n");
134 exit(1);
135 }
136 }
138 /* Switch to the fd cache. */
139 PR_SetFDCacheSize(0, FD_CACHE_SIZE);
141 for (i = 0; i < numfds; i++) {
142 fds[i] = PR_NewTCPSocket();
143 if (NULL == fds[i]) {
144 fprintf(stderr, "PR_NewTCPSocket failed\n");
145 exit(1);
146 }
147 #ifdef ORDER_PRESERVED
148 if (fds[i] != savefds[i]) {
149 fprintf(stderr, "fd cache malfunctioned\n");
150 exit(1);
151 }
152 #else
153 savefds[i] = fds[i];
154 #endif
155 }
156 for (i = 0; i < numfds; i++) {
157 if (PR_Close(savefds[i]) == PR_FAILURE) {
158 fprintf(stderr, "PR_Close failed\n");
159 exit(1);
160 }
161 }
163 for (i = 0; i < numfds; i++) {
164 fds[i] = PR_NewTCPSocket();
165 if (NULL == fds[i]) {
166 fprintf(stderr, "PR_NewTCPSocket failed\n");
167 exit(1);
168 }
169 if (fds[i] != savefds[i]) {
170 fprintf(stderr, "fd cache malfunctioned\n");
171 exit(1);
172 }
173 }
174 for (i = 0; i < numfds; i++) {
175 if (PR_Close(savefds[i]) == PR_FAILURE) {
176 fprintf(stderr, "PR_Close failed\n");
177 exit(1);
178 }
179 }
181 /* Switch to the fd stack. */
182 PR_SetFDCacheSize(0, 0);
184 for (i = 0; i < numfds; i++) {
185 fds[i] = PR_NewTCPSocket();
186 if (NULL == fds[i]) {
187 fprintf(stderr, "PR_NewTCPSocket failed\n");
188 exit(1);
189 }
190 #ifdef ORDER_PRESERVED
191 if (fds[i] != savefds[numfds-1-i]) {
192 fprintf(stderr, "fd stack malfunctioned\n");
193 exit(1);
194 }
195 #else
196 savefds[numfds-1-i];
197 #endif
198 }
199 for (i = 0; i < numfds; i++) {
200 if (PR_Close(savefds[i]) == PR_FAILURE) {
201 fprintf(stderr, "PR_Close failed\n");
202 exit(1);
203 }
204 }
206 for (i = 0; i < numfds; i++) {
207 fds[i] = PR_NewTCPSocket();
208 if (NULL == fds[i]) {
209 fprintf(stderr, "PR_NewTCPSocket failed\n");
210 exit(1);
211 }
212 if (fds[i] != savefds[numfds-1-i]) {
213 fprintf(stderr, "fd stack malfunctioned\n");
214 exit(1);
215 }
216 }
217 for (i = 0; i < numfds; i++) {
218 if (PR_Close(savefds[i]) == PR_FAILURE) {
219 fprintf(stderr, "PR_Close failed\n");
220 exit(1);
221 }
222 }
224 PR_Cleanup();
225 printf("PASS\n");
226 return 0;
227 }