Mercurial > hg > nginx
comparison src/core/ngx_garbage_collector.c @ 186:c1f3a3c7c5db
nginx-0.0.1-2003-11-17-00:49:42 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 16 Nov 2003 21:49:42 +0000 |
parents | d5f50cefc322 |
children | 02a715e85df1 |
comparison
equal
deleted
inserted
replaced
185:d5f50cefc322 | 186:c1f3a3c7c5db |
---|---|
4 | 4 |
5 | 5 |
6 typedef struct ngx_gc_s ngx_gc_t; | 6 typedef struct ngx_gc_s ngx_gc_t; |
7 | 7 |
8 typedef int (*ngx_gc_handler_pt) (ngx_gc_t *ctx, ngx_str_t *name, | 8 typedef int (*ngx_gc_handler_pt) (ngx_gc_t *ctx, ngx_str_t *name, |
9 ngx_file_info_t *fi); | 9 ngx_dir_t *dir); |
10 | |
11 | |
12 static int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name, | |
13 ngx_dir_t *dir); | |
10 | 14 |
11 struct ngx_gc_s { | 15 struct ngx_gc_s { |
12 ngx_path_t *path; | 16 ngx_path_t *path; |
13 u_int deleted; | 17 u_int deleted; |
14 off_t freed; | 18 off_t freed; |
76 path.level[1] = 2; | 80 path.level[1] = 2; |
77 path.level[2] = 0; | 81 path.level[2] = 0; |
78 | 82 |
79 ctx->path = &path; | 83 ctx->path = &path; |
80 ctx->log = log; | 84 ctx->log = log; |
85 ctx->handler = ngx_garbage_collector_temp_handler; | |
81 | 86 |
82 ngx_collect_garbage(ctx, &path.name, 0); | 87 ngx_collect_garbage(ctx, &path.name, 0); |
83 } | 88 } |
84 | 89 |
85 | 90 |
86 static int ngx_collect_garbage(ngx_gc_t *ctx, ngx_str_t *dname, int level) | 91 static int ngx_collect_garbage(ngx_gc_t *ctx, ngx_str_t *dname, int level) |
87 { | 92 { |
88 int nlen; | 93 int rc, len; |
89 char *last; | 94 char *last; |
90 ngx_str_t fname; | 95 ngx_err_t err; |
91 ngx_dir_t *dir; | 96 ngx_str_t fname, buf; |
92 ngx_dirent_t *de; | 97 ngx_dir_t dir; |
93 ngx_file_info_t fi; | 98 |
94 | 99 buf.len = 0; |
95 fname.len = 0; | 100 |
96 | 101 ngx_log_debug(ctx->log, "dir '%s':%d" _ dname->data _ dname->len); |
97 ngx_log_debug(ctx->log, "dir %s" _ dname->data); | 102 |
98 | 103 if (ngx_open_dir(dname, &dir) == NGX_ERROR) { |
99 dir = ngx_open_dir(dname->data); | 104 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, |
100 | 105 ngx_open_dir_n " \"%s\" failed", dname->data); |
101 if (dir == NULL) { | |
102 ngx_log_error(NGX_LOG_ERR, ctx->log, ngx_errno, | |
103 ngx_open_dir_n " \"%s\" failed", dname->data); | |
104 return NGX_ERROR; | 106 return NGX_ERROR; |
105 } | 107 } |
106 | 108 |
107 for ( ;; ) { | 109 for ( ;; ) { |
108 de = ngx_read_dir(dir); | 110 ngx_set_errno(0); |
109 | 111 if (ngx_read_dir(&dir) == NGX_ERROR) { |
110 if (de == NULL) { | 112 err = ngx_errno; |
111 if (fname.len) { | 113 |
112 ngx_free(fname.data); | 114 if (err != NGX_ENOMOREFILES) { |
113 } | 115 ngx_log_error(NGX_LOG_CRIT, ctx->log, err, |
116 ngx_read_dir_n " \"%s\" failed", dname->data); | |
117 rc = NGX_ERROR; | |
118 | |
119 } else { | |
120 rc = NGX_OK; | |
121 } | |
122 | |
114 break; | 123 break; |
115 } | 124 } |
116 | 125 |
117 ngx_log_debug(ctx->log, "file %s" _ de->d_name); | 126 len = ngx_de_namelen(&dir); |
118 | 127 |
119 #ifdef __FreeBSD__ | 128 ngx_log_debug(ctx->log, "name '%s':%d" _ ngx_de_name(&dir) _ len); |
120 nlen = de->d_namlen; | 129 |
121 #else | 130 if (len == 1 && ngx_de_name(&dir)[0] == '.') { |
122 nlen = ngx_strlen(de->d_name); | |
123 #endif | |
124 | |
125 if (nlen == 1 && de->d_name[0] == '.') { | |
126 continue; | 131 continue; |
127 } | 132 } |
128 | 133 |
129 if (nlen == 2 && de->d_name[0] == '.' && de->d_name[1] == '.') { | 134 if (len == 2 |
135 && ngx_de_name(&dir)[0] == '.' | |
136 && ngx_de_name(&dir)[1] == '.') | |
137 { | |
130 continue; | 138 continue; |
131 } | 139 } |
132 | 140 |
133 if (dname->len + 1 + nlen > fname.len) { | 141 fname.len = dname->len + 1+ len; |
134 if (fname.len) { | 142 |
135 ngx_free(fname.data); | 143 if (fname.len + NGX_DIR_MASK_LEN > buf.len) { |
136 } | 144 |
137 | 145 if (buf.len) { |
138 fname.len = dname->len + 1 + nlen; | 146 ngx_free(buf.data); |
139 | 147 } |
140 if (!(fname.data = ngx_alloc(fname.len + 1, ctx->log))) { | 148 |
149 buf.len = dname->len + 1 + len + NGX_DIR_MASK_LEN; | |
150 | |
151 if (!(buf.data = ngx_alloc(buf.len + 1, ctx->log))) { | |
141 return NGX_ABORT; | 152 return NGX_ABORT; |
142 } | 153 } |
143 } | 154 } |
144 | 155 |
145 last = ngx_cpymem(fname.data, dname->data, dname->len); | 156 last = ngx_cpymem(buf.data, dname->data, dname->len); |
146 *last++ = '/'; | 157 *last++ = '/'; |
147 ngx_memcpy(last, de->d_name, nlen + 1); | 158 ngx_memcpy(last, ngx_de_name(&dir), len + 1); |
148 | 159 fname.data = buf.data; |
149 ngx_log_debug(ctx->log, "de %s" _ fname.data); | 160 |
150 | 161 ngx_log_debug(ctx->log, "path %s" _ fname.data); |
151 if (ngx_file_type(fname.data, &fi) == NGX_FILE_ERROR) { | 162 |
152 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, | 163 if (!dir.info_valid) { |
153 ngx_file_type_n " \"%s\" failed", fname.data); | 164 if (ngx_de_info(fname.data, &dir) == NGX_FILE_ERROR) { |
154 continue; | 165 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, |
155 } | 166 ngx_de_info_n " \"%s\" failed", fname.data); |
156 | 167 continue; |
157 if (ngx_is_dir((&fi))) { | 168 } |
169 } | |
170 | |
171 if (ngx_de_is_dir(&dir)) { | |
158 | 172 |
159 ngx_log_debug(ctx->log, "enter %s" _ fname.data); | 173 ngx_log_debug(ctx->log, "enter %s" _ fname.data); |
160 | 174 |
161 if (level == -1 | 175 if (level == -1 |
162 /* there can not be directory on the last level */ | 176 /* there can not be directory on the last level */ |
163 || level == NGX_MAX_PATH_LEVEL | 177 || level == NGX_MAX_PATH_LEVEL |
164 /* an directory from the old path hierarchy */ | 178 /* an directory from the old path hierarchy */ |
165 || nlen != ctx->path->level[level]) | 179 || len != ctx->path->level[level]) |
166 { | 180 { |
167 if (ngx_collect_garbage(ctx, &fname, -1) == NGX_ABORT) { | 181 if (ngx_collect_garbage(ctx, &fname, -1) == NGX_ABORT) { |
168 return NGX_ABORT; | 182 return NGX_ABORT; |
169 } | 183 } |
184 | |
185 fname.data[fname.len] = '\0'; | |
170 | 186 |
171 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0, | 187 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0, |
172 "delete old hierachy directory \"%s\"", | 188 "delete old hierachy directory \"%s\"", |
173 fname.data); | 189 fname.data); |
174 | 190 |
176 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, | 192 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, |
177 ngx_delete_dir_n " \"%s\" failed", | 193 ngx_delete_dir_n " \"%s\" failed", |
178 fname.data); | 194 fname.data); |
179 } else { | 195 } else { |
180 ctx->deleted++; | 196 ctx->deleted++; |
181 ctx->freed += ngx_file_size((&fi)); | 197 ctx->freed += ngx_de_size(&dir); |
182 } | 198 } |
183 | 199 |
184 continue; | 200 continue; |
185 } | 201 } |
186 | 202 |
187 if (ngx_collect_garbage(ctx, &fname, level + 1) == NGX_ABORT) { | 203 if (ngx_collect_garbage(ctx, &fname, level + 1) == NGX_ABORT) { |
188 return NGX_ABORT; | 204 return NGX_ABORT; |
189 } | 205 } |
190 | 206 |
191 } else if (ngx_is_file((&fi))) { | 207 } else if (ngx_de_is_file(&dir)) { |
208 | |
209 ngx_log_debug(ctx->log, "file %s" _ fname.data); | |
192 | 210 |
193 if (level == -1 | 211 if (level == -1 |
194 || (level < NGX_MAX_PATH_LEVEL && ctx->path->level[level] != 0)) | 212 || (level < NGX_MAX_PATH_LEVEL && ctx->path->level[level] != 0)) |
195 { | 213 { |
196 if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) { | 214 if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) { |
197 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, | 215 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, |
198 ngx_delete_file_n " \"%s\" failed", | 216 ngx_delete_file_n " \"%s\" failed", |
199 fname.data); | 217 fname.data); |
200 } else { | 218 } else { |
201 ctx->deleted++; | 219 ctx->deleted++; |
202 ctx->freed += ngx_file_size((&fi)); | 220 ctx->freed += ngx_de_size(&dir); |
203 } | 221 } |
204 | 222 |
205 continue; | 223 continue; |
206 } | 224 } |
207 | 225 |
208 if (ctx->handler(ctx, &fname, &fi) == NGX_ABORT) { | 226 if (ctx->handler(ctx, &fname, &dir) == NGX_ABORT) { |
209 return NGX_ABORT; | 227 return NGX_ABORT; |
210 } | 228 } |
211 | 229 |
212 } else { | 230 } else { |
213 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, | 231 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, |
216 if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) { | 234 if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) { |
217 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, | 235 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, |
218 ngx_delete_file_n " \"%s\" failed", fname.data); | 236 ngx_delete_file_n " \"%s\" failed", fname.data); |
219 } else { | 237 } else { |
220 ctx->deleted++; | 238 ctx->deleted++; |
221 ctx->freed += ngx_file_size((&fi)); | 239 ctx->freed += ngx_de_size(&dir); |
222 } | 240 } |
223 } | 241 } |
224 } | 242 } |
225 | 243 |
226 return NGX_OK; | 244 if (buf.len) { |
227 } | 245 ngx_free(buf.data); |
228 | 246 } |
229 | 247 |
230 int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name, | 248 if (ngx_close_dir(&dir) == NGX_ERROR) { |
231 ngx_file_info_t *fi) | 249 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, |
250 ngx_close_dir_n " \"%s\" failed", fname.data); | |
251 } | |
252 | |
253 return rc; | |
254 } | |
255 | |
256 | |
257 static int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name, | |
258 ngx_dir_t *dir) | |
232 { | 259 { |
233 /* | 260 /* |
234 * we use mtime only and do not use atime because: | 261 * we use mtime only and do not use atime because: |
235 * on NTFS access time has a resolution of 1 hour, | 262 * on NTFS access time has a resolution of 1 hour, |
236 * on NT FAT access time has a resolution of 1 day, | 263 * on NT FAT access time has a resolution of 1 day, |
237 * Unices have mount option "noatime" | 264 * Unices have mount option "noatime" |
238 */ | 265 */ |
239 | 266 |
240 if (ngx_cached_time - ngx_file_mtime(fi) < 3600) { | 267 if (ngx_cached_time - ngx_de_mtime(dir) < 3600) { |
241 return NGX_OK; | 268 return NGX_OK; |
242 } | 269 } |
243 | 270 |
244 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0, | 271 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0, |
245 "delete stale temporary \"%s\"", name->data); | 272 "delete stale temporary \"%s\"", name->data); |
249 ngx_delete_file_n " \"%s\" failed", name->data); | 276 ngx_delete_file_n " \"%s\" failed", name->data); |
250 return NGX_ERROR; | 277 return NGX_ERROR; |
251 } | 278 } |
252 | 279 |
253 ctx->deleted++; | 280 ctx->deleted++; |
254 ctx->freed += ngx_file_size(fi); | 281 ctx->freed += ngx_de_size(dir); |
255 return NGX_OK; | 282 return NGX_OK; |
256 } | 283 } |