Changeset 237 for trunk/libtransmission
- Timestamp:
- Apr 22, 2006, 9:39:17 PM (17 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/net.c
r236 r237 23 23 #include "transmission.h" 24 24 25 /*********************************************************************** 26 * DNS resolution 27 **********************************************************************/ 28 29 /*********************************************************************** 30 * tr_netResolve 31 *********************************************************************** 32 * Synchronous "resolution": only works with character strings 33 * representing numbers expressed in the Internet standard `.' notation. 34 * Returns a non-zero value if an error occurs. 35 **********************************************************************/ 36 int tr_netResolve( char * address, struct in_addr * addr ) 37 { 38 addr->s_addr = inet_addr( address ); 39 return ( addr->s_addr == 0xFFFFFFFF ); 40 } 41 42 /* TODO: Make this code reentrant */ 43 static tr_thread_t resolveThread; 44 static tr_lock_t resolveLock; 45 static volatile int resolveDie; 46 static tr_resolve_t * resolveQueue; 47 48 static void resolveRelease ( tr_resolve_t * ); 49 static void resolveFunc ( void * ); 50 51 struct tr_resolve_s 52 { 53 int status; 54 char * address; 55 struct in_addr addr; 56 57 int refcount; 58 tr_resolve_t * next; 59 }; 60 61 /*********************************************************************** 62 * tr_netResolveThreadInit 63 *********************************************************************** 64 * Initializes the static variables used for resolution and launch the 65 * gethostbyname thread. 66 **********************************************************************/ 67 void tr_netResolveThreadInit() 68 { 69 resolveDie = 0; 70 resolveQueue = NULL; 71 tr_lockInit( &resolveLock ); 72 tr_threadCreate( &resolveThread, resolveFunc, NULL ); 73 } 74 75 /*********************************************************************** 76 * tr_netResolveThreadClose 77 *********************************************************************** 78 * Notices the gethostbyname thread that is should terminate. Doesn't 79 * wait until it does, in case it is stuck in a resolution: we let it 80 * die and clean itself up. 81 **********************************************************************/ 82 void tr_netResolveThreadClose() 83 { 84 tr_lockLock( &resolveLock ); 85 resolveDie = 1; 86 tr_lockUnlock( &resolveLock ); 87 tr_wait( 200 ); 88 } 89 90 /*********************************************************************** 91 * tr_netResolveInit 92 *********************************************************************** 93 * Adds an address to the resolution queue. 94 **********************************************************************/ 95 tr_resolve_t * tr_netResolveInit( char * address ) 96 { 97 tr_resolve_t * r; 98 99 r = malloc( sizeof( tr_resolve_t ) ); 100 r->status = TR_RESOLVE_WAIT; 101 r->address = strdup( address ); 102 r->refcount = 2; 103 r->next = NULL; 104 105 tr_lockLock( &resolveLock ); 106 if( !resolveQueue ) 107 { 108 resolveQueue = r; 109 } 110 else 111 { 112 tr_resolve_t * iter; 113 for( iter = resolveQueue; iter->next; iter = iter->next ); 114 iter->next = r; 115 } 116 tr_lockUnlock( &resolveLock ); 117 118 return r; 119 } 120 121 /*********************************************************************** 122 * tr_netResolvePulse 123 *********************************************************************** 124 * Checks the current status of a resolution. 125 **********************************************************************/ 126 int tr_netResolvePulse( tr_resolve_t * r, struct in_addr * addr ) 127 { 128 int ret; 129 130 tr_lockLock( &resolveLock ); 131 ret = r->status; 132 if( ret == TR_RESOLVE_OK ) 133 { 134 *addr = r->addr; 135 } 136 tr_lockUnlock( &resolveLock ); 137 138 return ret; 139 } 140 141 /*********************************************************************** 142 * tr_netResolveClose 143 *********************************************************************** 144 * 145 **********************************************************************/ 146 void tr_netResolveClose( tr_resolve_t * r ) 147 { 148 resolveRelease( r ); 149 } 150 151 /*********************************************************************** 152 * resolveRelease 153 *********************************************************************** 154 * The allocated tr_resolve_t structures should be freed when 155 * tr_netResolveClose was called *and* it was removed from the queue. 156 * This can happen in any order, so we use a refcount to know we can 157 * take it out. 158 **********************************************************************/ 159 static void resolveRelease( tr_resolve_t * r ) 160 { 161 if( --r->refcount < 1 ) 162 { 163 free( r->address ); 164 free( r ); 165 } 166 } 167 168 /*********************************************************************** 169 * resolveFunc 170 *********************************************************************** 171 * Keeps waiting for addresses to resolve, and removes them from the 172 * queue once resolution is done. 173 **********************************************************************/ 174 static void resolveFunc( void * unused ) 175 { 176 tr_resolve_t * r; 177 struct hostent * host; 178 179 tr_dbg( "Resolve thread started" ); 180 181 tr_lockLock( &resolveLock ); 182 183 while( !resolveDie ) 184 { 185 if( !( r = resolveQueue ) ) 186 { 187 /* TODO: Use a condition wait */ 188 tr_lockUnlock( &resolveLock ); 189 tr_wait( 50 ); 190 tr_lockLock( &resolveLock ); 191 continue; 192 } 193 194 /* Blocking resolution */ 195 tr_lockUnlock( &resolveLock ); 196 host = gethostbyname( r->address ); 197 tr_lockLock( &resolveLock ); 198 199 if( host ) 200 { 201 memcpy( &r->addr, host->h_addr, host->h_length ); 202 r->status = TR_RESOLVE_OK; 203 } 204 else 205 { 206 r->status = TR_RESOLVE_ERROR; 207 } 208 209 resolveQueue = r->next; 210 resolveRelease( r ); 211 } 212 213 /* Clean up */ 214 tr_lockUnlock( &resolveLock ); 215 tr_lockClose( &resolveLock ); 216 while( ( r = resolveQueue ) ) 217 { 218 resolveQueue = r->next; 219 resolveRelease( r ); 220 } 221 222 tr_dbg( "Resolve thread exited" ); 223 } 224 225 226 /*********************************************************************** 227 * TCP sockets 228 **********************************************************************/ 229 25 230 static int makeSocketNonBlocking( int s ) 26 231 { … … 59 264 } 60 265 61 struct tr_resolve_s62 {63 int status;64 char * address;65 struct in_addr addr;66 67 tr_lock_t lock;68 tr_thread_t thread;69 int orphan;70 };71 72 /* Hem, global variable. Initialized from tr_init(). */73 tr_lock_t gethostbynameLock;74 75 static void resolveFunc( void * _r )76 {77 tr_resolve_t * r = _r;78 struct hostent * host;79 80 tr_lockLock( &r->lock );81 82 r->addr.s_addr = inet_addr( r->address );83 if( r->addr.s_addr != 0xFFFFFFFF )84 {85 /* This was an IP address, no resolving required */86 r->status = TR_RESOLVE_OK;87 goto resolveDone;88 }89 90 tr_lockLock( &gethostbynameLock );91 tr_lockUnlock( &r->lock );92 host = gethostbyname( r->address );93 tr_lockLock( &r->lock );94 if( host )95 {96 memcpy( &r->addr, host->h_addr, host->h_length );97 r->status = TR_RESOLVE_OK;98 }99 else100 {101 r->status = TR_RESOLVE_ERROR;102 }103 tr_lockUnlock( &gethostbynameLock );104 105 resolveDone:106 if( r->orphan )107 {108 /* tr_netResolveClose was closed already. Free memory */109 tr_lockUnlock( &r->lock );110 tr_lockClose( &r->lock );111 free( r );112 }113 else114 {115 tr_lockUnlock( &r->lock );116 }117 }118 119 tr_resolve_t * tr_netResolveInit( char * address )120 {121 tr_resolve_t * r = malloc( sizeof( tr_resolve_t ) );122 123 r->status = TR_RESOLVE_WAIT;124 r->address = address;125 126 tr_lockInit( &r->lock );127 tr_threadCreate( &r->thread, resolveFunc, r );128 r->orphan = 0;129 130 return r;131 }132 133 int tr_netResolvePulse( tr_resolve_t * r, struct in_addr * addr )134 {135 int ret;136 137 tr_lockLock( &r->lock );138 ret = r->status;139 if( ret == TR_RESOLVE_OK )140 {141 *addr = r->addr;142 }143 tr_lockUnlock( &r->lock );144 145 return ret;146 }147 148 void tr_netResolveClose( tr_resolve_t * r )149 {150 tr_lockLock( &r->lock );151 if( r->status == TR_RESOLVE_WAIT )152 {153 /* Let the thread die */154 r->orphan = 1;155 tr_lockUnlock( &r->lock );156 return;157 }158 tr_lockUnlock( &r->lock );159 160 /* Clean up */161 tr_threadJoin( &r->thread );162 tr_lockClose( &r->lock );163 free( r );164 }165 166 /* Blocking version */167 int tr_netResolve( char * address, struct in_addr * addr )168 {169 addr->s_addr = inet_addr( address );170 return ( addr->s_addr == 0xFFFFFFFF );171 }172 173 266 int tr_netOpen( struct in_addr addr, in_port_t port ) 174 267 { -
trunk/libtransmission/net.h
r236 r237 21 21 *****************************************************************************/ 22 22 23 23 24 /*********************************************************************** 24 25 * DNS resolution 25 26 **********************************************************************/ 26 27 /* Synchronous version: only works with character strings representing28 numbers expressed in the Internet standard `.' notation */29 27 int tr_netResolve( char *, struct in_addr * ); 30 28 31 /* Asynchronous version */32 29 #define TR_RESOLVE_WAIT 0 33 30 #define TR_RESOLVE_ERROR 1 34 31 #define TR_RESOLVE_OK 2 35 32 typedef struct tr_resolve_s tr_resolve_t; 33 void tr_netResolveThreadInit(); 34 void tr_netResolveThreadClose(); 36 35 tr_resolve_t * tr_netResolveInit( char * ); 37 36 int tr_netResolvePulse( tr_resolve_t *, struct in_addr * ); -
trunk/libtransmission/transmission.c
r219 r237 31 31 static void acceptStop( tr_handle_t * h ); 32 32 33 /* Used in tr_netResolve */34 extern tr_lock_t gethostbynameLock;35 36 33 /*********************************************************************** 37 34 * tr_init … … 44 41 int i, r; 45 42 46 tr_ lockInit( &gethostbynameLock);43 tr_netResolveThreadInit(); 47 44 48 45 h = calloc( sizeof( tr_handle_t ), 1 ); … … 541 538 free( h ); 542 539 543 tr_ lockClose( &gethostbynameLock);540 tr_netResolveThreadClose(); 544 541 } 545 542
Note: See TracChangeset
for help on using the changeset viewer.