Changeset 1420 for trunk/libtransmission/fdlimit.c
- Timestamp:
- Jan 21, 2007, 7:16:18 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/fdlimit.c
r1408 r1420 29 29 connections to trackers */ 30 30 31 /*********************************************************************** 32 * Structures 33 **********************************************************************/ 31 34 typedef struct tr_openFile_s 32 35 { … … 43 46 44 47 uint64_t date; 45 46 }tr_openFile_t;47 48 struct tr_fd_s48 } 49 tr_openFile_t; 50 51 typedef struct tr_fd_s 49 52 { 50 53 tr_lock_t lock; … … 57 60 58 61 tr_openFile_t open[TR_MAX_OPEN_FILES]; 59 }; 62 } 63 tr_fd_t; 64 65 static tr_fd_t * gFd = NULL; 60 66 61 67 /*********************************************************************** … … 63 69 **********************************************************************/ 64 70 static int ErrorFromErrno(); 65 static int OpenFile( tr_fd_t * f, int i, char * folder, char * name, 66 int write ); 67 static void CloseFile( tr_fd_t * f, int i ); 71 static int OpenFile( int i, char * folder, char * name, int write ); 72 static void CloseFile( int i ); 68 73 69 74 … … 71 76 * tr_fdInit 72 77 **********************************************************************/ 73 tr_fd_t * tr_fdInit() 74 { 75 tr_fd_t * f; 78 void tr_fdInit() 79 { 76 80 int i, j, s[4096]; 77 81 78 f = calloc( sizeof( tr_fd_t ), 1 ); 82 if( gFd ) 83 { 84 tr_err( "tr_fdInit was called before!" ); 85 return; 86 } 87 88 gFd = calloc( sizeof( tr_fd_t ), 1 ); 79 89 80 90 /* Init lock and cond */ 81 tr_lockInit( & f->lock );82 tr_condInit( & f->cond );91 tr_lockInit( &gFd->lock ); 92 tr_condInit( &gFd->cond ); 83 93 84 94 /* Detect the maximum number of open files or sockets */ … … 97 107 tr_dbg( "%d usable file descriptors", i ); 98 108 99 f->reserved = 0;100 f->normal = 0;101 102 f->normalMax = i - TR_RESERVED_FDS - 10;109 gFd->reserved = 0; 110 gFd->normal = 0; 111 112 gFd->normalMax = i - TR_RESERVED_FDS - 10; 103 113 /* To be safe, in case the UI needs to write a preferences file 104 114 or something */ … … 106 116 for( i = 0; i < TR_MAX_OPEN_FILES; i++ ) 107 117 { 108 f->open[i].status = STATUS_INVALID; 109 } 110 111 return f; 118 gFd->open[i].status = STATUS_INVALID; 119 } 112 120 } 113 121 … … 115 123 * tr_fdFileOpen 116 124 **********************************************************************/ 117 int tr_fdFileOpen( tr_fd_t * f,char * folder, char * name, int write )125 int tr_fdFileOpen( char * folder, char * name, int write ) 118 126 { 119 127 int i, winner, ret; 120 128 uint64_t date; 121 129 122 tr_lockLock( & f->lock );130 tr_lockLock( &gFd->lock ); 123 131 124 132 /* Is it already open? */ 125 133 for( i = 0; i < TR_MAX_OPEN_FILES; i++ ) 126 134 { 127 if( f->open[i].status & STATUS_INVALID ||128 strcmp( folder, f->open[i].folder ) ||129 strcmp( name, f->open[i].name ) )135 if( gFd->open[i].status & STATUS_INVALID || 136 strcmp( folder, gFd->open[i].folder ) || 137 strcmp( name, gFd->open[i].name ) ) 130 138 { 131 139 continue; 132 140 } 133 if( f->open[i].status & STATUS_CLOSING )141 if( gFd->open[i].status & STATUS_CLOSING ) 134 142 { 135 143 /* File is being closed by another thread, wait until 136 144 * it's done before we reopen it */ 137 tr_condWait( & f->cond, &f->lock );145 tr_condWait( &gFd->cond, &gFd->lock ); 138 146 i = -1; 139 147 continue; 140 148 } 141 if( f->open[i].write < write )149 if( gFd->open[i].write < write ) 142 150 { 143 151 /* File is open read-only and needs to be closed then 144 152 * re-opened read-write */ 145 CloseFile( f,i );153 CloseFile( i ); 146 154 continue; 147 155 } … … 153 161 for( i = 0; i < TR_MAX_OPEN_FILES; i++ ) 154 162 { 155 if( f->open[i].status & STATUS_INVALID )163 if( gFd->open[i].status & STATUS_INVALID ) 156 164 { 157 165 winner = i; … … 168 176 for( i = 0; i < TR_MAX_OPEN_FILES; i++ ) 169 177 { 170 if( !( f->open[i].status & STATUS_UNUSED ) )178 if( !( gFd->open[i].status & STATUS_UNUSED ) ) 171 179 { 172 180 continue; 173 181 } 174 if( f->open[i].date < date )182 if( gFd->open[i].date < date ) 175 183 { 176 184 winner = i; 177 date = f->open[i].date;185 date = gFd->open[i].date; 178 186 } 179 187 } … … 181 189 if( winner >= 0 ) 182 190 { 183 CloseFile( f,winner );191 CloseFile( winner ); 184 192 goto open; 185 193 } 186 194 187 195 /* All used! Wait a bit and try again */ 188 tr_condWait( & f->cond, &f->lock );196 tr_condWait( &gFd->cond, &gFd->lock ); 189 197 } 190 198 191 199 open: 192 if( ( ret = OpenFile( f,winner, folder, name, write ) ) )193 { 194 tr_lockUnlock( & f->lock );200 if( ( ret = OpenFile( winner, folder, name, write ) ) ) 201 { 202 tr_lockUnlock( &gFd->lock ); 195 203 return ret; 196 204 } 197 snprintf( f->open[winner].folder, MAX_PATH_LENGTH, "%s", folder );198 snprintf( f->open[winner].name, MAX_PATH_LENGTH, "%s", name );199 f->open[winner].write = write;205 snprintf( gFd->open[winner].folder, MAX_PATH_LENGTH, "%s", folder ); 206 snprintf( gFd->open[winner].name, MAX_PATH_LENGTH, "%s", name ); 207 gFd->open[winner].write = write; 200 208 201 209 done: 202 f->open[winner].status = STATUS_USED;203 f->open[winner].date = tr_date();204 tr_lockUnlock( & f->lock );210 gFd->open[winner].status = STATUS_USED; 211 gFd->open[winner].date = tr_date(); 212 tr_lockUnlock( &gFd->lock ); 205 213 206 return f->open[winner].file;214 return gFd->open[winner].file; 207 215 } 208 216 … … 210 218 * tr_fdFileRelease 211 219 **********************************************************************/ 212 void tr_fdFileRelease( tr_fd_t * f,int file )220 void tr_fdFileRelease( int file ) 213 221 { 214 222 int i; 215 tr_lockLock( & f->lock );223 tr_lockLock( &gFd->lock ); 216 224 217 225 for( i = 0; i < TR_MAX_OPEN_FILES; i++ ) 218 226 { 219 if( f->open[i].file == file )220 { 221 f->open[i].status = STATUS_UNUSED;227 if( gFd->open[i].file == file ) 228 { 229 gFd->open[i].status = STATUS_UNUSED; 222 230 break; 223 231 } 224 232 } 225 233 226 tr_condSignal( & f->cond );227 tr_lockUnlock( & f->lock );234 tr_condSignal( &gFd->cond ); 235 tr_lockUnlock( &gFd->lock ); 228 236 } 229 237 … … 231 239 * tr_fdFileClose 232 240 **********************************************************************/ 233 void tr_fdFileClose( tr_fd_t * f,char * folder, char * name )241 void tr_fdFileClose( char * folder, char * name ) 234 242 { 235 243 int i; 236 244 237 tr_lockLock( & f->lock );245 tr_lockLock( &gFd->lock ); 238 246 239 247 for( i = 0; i < TR_MAX_OPEN_FILES; i++ ) 240 248 { 241 if( f->open[i].status & STATUS_INVALID )249 if( gFd->open[i].status & STATUS_INVALID ) 242 250 { 243 251 continue; 244 252 } 245 if( !strcmp( folder, f->open[i].folder ) &&246 !strcmp( name, f->open[i].name ) )247 { 248 CloseFile( f,i );249 } 250 } 251 252 tr_lockUnlock( & f->lock );253 if( !strcmp( folder, gFd->open[i].folder ) && 254 !strcmp( name, gFd->open[i].name ) ) 255 { 256 CloseFile( i ); 257 } 258 } 259 260 tr_lockUnlock( &gFd->lock ); 253 261 } 254 262 … … 256 264 * tr_fdSocketWillCreate 257 265 **********************************************************************/ 258 int tr_fdSocketWillCreate( tr_fd_t * f,int reserved )266 int tr_fdSocketWillCreate( int reserved ) 259 267 { 260 268 int ret; 261 269 262 tr_lockLock( & f->lock );270 tr_lockLock( &gFd->lock ); 263 271 264 272 if( reserved ) 265 273 { 266 if( f->reserved < TR_RESERVED_FDS )274 if( gFd->reserved < TR_RESERVED_FDS ) 267 275 { 268 276 ret = 0; 269 ( f->reserved)++;277 (gFd->reserved)++; 270 278 } 271 279 else … … 276 284 else 277 285 { 278 if( f->normal < f->normalMax )286 if( gFd->normal < gFd->normalMax ) 279 287 { 280 288 ret = 0; 281 ( f->normal)++;289 (gFd->normal)++; 282 290 } 283 291 else … … 287 295 } 288 296 289 tr_lockUnlock( & f->lock );297 tr_lockUnlock( &gFd->lock ); 290 298 291 299 return ret; … … 295 303 * tr_fdSocketClosed 296 304 **********************************************************************/ 297 void tr_fdSocketClosed( tr_fd_t * f,int reserved )298 { 299 tr_lockLock( & f->lock );305 void tr_fdSocketClosed( int reserved ) 306 { 307 tr_lockLock( &gFd->lock ); 300 308 301 309 if( reserved ) 302 310 { 303 ( f->reserved)--;311 (gFd->reserved)--; 304 312 } 305 313 else 306 314 { 307 ( f->normal)--;308 } 309 310 tr_lockUnlock( & f->lock );315 (gFd->normal)--; 316 } 317 318 tr_lockUnlock( &gFd->lock ); 311 319 } 312 320 … … 314 322 * tr_fdClose 315 323 **********************************************************************/ 316 void tr_fdClose( tr_fd_t * f)317 { 318 tr_lockClose( & f->lock );319 tr_condClose( & f->cond );320 free( f);324 void tr_fdClose() 325 { 326 tr_lockClose( &gFd->lock ); 327 tr_condClose( &gFd->cond ); 328 free( gFd ); 321 329 } 322 330 … … 341 349 * 342 350 **********************************************************************/ 343 static int OpenFile( tr_fd_t * f, int i, char * folder, char * name, 344 int write ) 345 { 346 tr_openFile_t * file = &f->open[i]; 351 static int OpenFile( int i, char * folder, char * name, int write ) 352 { 353 tr_openFile_t * file = &gFd->open[i]; 347 354 struct stat sb; 348 355 char * path; … … 411 418 * threads. 412 419 **********************************************************************/ 413 static void CloseFile( tr_fd_t * f,int i )414 { 415 tr_openFile_t * file = & f->open[i];420 static void CloseFile( int i ) 421 { 422 tr_openFile_t * file = &gFd->open[i]; 416 423 417 424 /* If it's already being closed by another thread, just wait till … … 419 426 while( file->status & STATUS_CLOSING ) 420 427 { 421 tr_condWait( & f->cond, &f->lock );428 tr_condWait( &gFd->cond, &gFd->lock ); 422 429 } 423 430 if( file->status & STATUS_INVALID ) … … 433 440 tr_dbg( "Closing %s in %s (%d)", file->name, file->folder, file->write ); 434 441 file->status = STATUS_CLOSING; 435 tr_lockUnlock( & f->lock );442 tr_lockUnlock( &gFd->lock ); 436 443 close( file->file ); 437 tr_lockLock( & f->lock );444 tr_lockLock( &gFd->lock ); 438 445 file->status = STATUS_INVALID; 439 tr_condSignal( & f->cond );440 } 441 446 tr_condSignal( &gFd->cond ); 447 } 448
Note: See TracChangeset
for help on using the changeset viewer.