(trunk libT) #2842 "Transmission crashes randomly on ARM-based Synology NAS" -- experimental commit based on giovannibajo's suggestion in comment:39 about the list struct's alignment

This commit is contained in:
Charles Kerr 2010-04-23 23:45:44 +00:00
parent 358bce52fd
commit 4f5670f9c0
4 changed files with 14 additions and 114 deletions

View File

@ -157,50 +157,3 @@ tr_list_size( const tr_list * list )
return size;
}
/*
* Double-linked list with easy memory management and fast
* insert/remove operations
*/
void
__tr_list_insert( struct __tr_list * list,
struct __tr_list * prev,
struct __tr_list * next)
{
next->prev = list;
list->next = next;
list->prev = prev;
prev->next = list;
}
static void
__tr_list_splice( struct __tr_list * prev,
struct __tr_list * next)
{
next->prev = prev;
prev->next = next;
}
void
__tr_list_remove( struct __tr_list * head )
{
__tr_list_splice( head->prev, head->next );
head->next = head->prev = NULL;
}
void
__tr_list_destroy( struct __tr_list * head,
__tr_list_free_t func)
{
while ( head->next != head )
{
struct __tr_list * list = head->next;
__tr_list_splice( list->prev, list->next );
func( list );
}
}

View File

@ -101,51 +101,6 @@ tr_list* tr_list_find( tr_list * list,
TrListCompareFunc compare_func );
/** @brief Double-linked list with easy memory management and fast insert/remove operations */
struct __tr_list
{
struct __tr_list * next, * prev;
};
/**
* @brief Given a __tr_list node that's embedded in a struct, returns a pointer to the struct.
* @param ptr pointer to the embedded __tr_list
* @param type struct type that has contains the __tr_list
* @param field the name of the struct's _tr_list field
*/
#define __tr_list_entry(ptr,type,field) ((type*) (((char*)ptr) - offsetof(type,field)))
typedef int ( *__tr_list_cmp_t ) ( const void * a, const void * b );
typedef void ( *__tr_list_free_t )( void * );
/** @brief Init @head as an empty list. */
static inline void
__tr_list_init( struct __tr_list * head )
{
head->next = head->prev = head;
}
/** @brief Insert @list between @prev and @next. */
void
__tr_list_insert( struct __tr_list * list,
struct __tr_list * prev,
struct __tr_list * next);
/** @brief Append @list to the end of @head. */
static inline void
__tr_list_append( struct __tr_list * head, struct __tr_list * list)
{
__tr_list_insert( list, head->prev, head );
}
/** @brief Remove @head from the list it is in. */
void __tr_list_remove( struct __tr_list * head );
/** @brief Destroy the list and free all nodes */
void __tr_list_destroy( struct __tr_list * head, __tr_list_free_t func );
/* @} */
#endif /* TR_LIST_H */

View File

@ -75,7 +75,6 @@ struct tr_datatype
{
tr_bool isPieceData;
size_t length;
struct __tr_list head;
};
/***
@ -87,7 +86,8 @@ didWriteWrapper( tr_peerIo * io, size_t bytes_transferred )
{
while( bytes_transferred && tr_isPeerIo( io ) )
{
struct tr_datatype * next = __tr_list_entry( io->outbuf_datatypes.next, struct tr_datatype, head );
struct tr_datatype * next = io->outbuf_datatypes->data;
const size_t payload = MIN( next->length, bytes_transferred );
const size_t overhead = guessPacketOverhead( payload );
@ -104,7 +104,7 @@ didWriteWrapper( tr_peerIo * io, size_t bytes_transferred )
bytes_transferred -= payload;
next->length -= payload;
if( !next->length ) {
__tr_list_remove( io->outbuf_datatypes.next );
tr_list_pop_front( &io->outbuf_datatypes );
tr_free( next );
}
}
@ -413,8 +413,6 @@ tr_peerIoNew( tr_session * session,
event_set( &io->event_read, io->socket, EV_READ, event_read_cb, io );
event_set( &io->event_write, io->socket, EV_WRITE, event_write_cb, io );
__tr_list_init( &io->outbuf_datatypes );
return io;
}
@ -463,6 +461,7 @@ event_enable( tr_peerIo * io, short event )
assert( tr_amInEventThread( io->session ) );
assert( io->session != NULL );
assert( io->session->events != NULL );
assert( io->socket >= 0 );
assert( event_initialized( &io->event_read ) );
assert( event_initialized( &io->event_write ) );
@ -527,13 +526,6 @@ tr_peerIoSetEnabled( tr_peerIo * io,
****
***/
static void
trDatatypeFree( void * data )
{
struct tr_datatype * dt = __tr_list_entry( data, struct tr_datatype, head );
tr_free(dt);
}
static void
io_dtor( void * vio )
{
@ -550,7 +542,7 @@ io_dtor( void * vio )
evbuffer_free( io->inbuf );
tr_netClose( io->session, io->socket );
tr_cryptoFree( io->crypto );
__tr_list_destroy( &io->outbuf_datatypes, trDatatypeFree );
tr_list_free( &io->outbuf_datatypes, tr_free );
memset( io, ~0, sizeof( tr_peerIo ) );
tr_free( io );
@ -816,9 +808,7 @@ tr_peerIoWrite( tr_peerIo * io,
datatype = tr_new( struct tr_datatype, 1 );
datatype->isPieceData = isPieceData != 0;
datatype->length = byteCount;
__tr_list_init( &datatype->head );
__tr_list_append( &io->outbuf_datatypes, &datatype->head );
tr_list_append( &io->outbuf_datatypes, datatype );
switch( io->encryptionMode )
{
@ -997,15 +987,17 @@ int
tr_peerIoFlushOutgoingProtocolMsgs( tr_peerIo * io )
{
size_t byteCount = 0;
struct __tr_list * walk;
struct __tr_list * fencepost = &io->outbuf_datatypes;
tr_list * it;
/* count up how many bytes are used by non-piece-data messages
at the front of our outbound queue */
for( walk=fencepost->next; walk!=fencepost; walk=walk->next ) {
struct tr_datatype * d = __tr_list_entry( walk, struct tr_datatype, head );
for( it=io->outbuf_datatypes; it!=NULL; it=it->next )
{
struct tr_datatype * d = it->data;
if( d->isPieceData )
break;
byteCount += d->length;
}

View File

@ -27,7 +27,7 @@
#include "transmission.h"
#include "bandwidth.h"
#include "list.h" /* __tr_list */
#include "list.h" /* tr_list */
#include "net.h" /* tr_address */
struct evbuffer;
@ -106,7 +106,7 @@ typedef struct tr_peerIo
struct evbuffer * inbuf;
struct evbuffer * outbuf;
struct __tr_list outbuf_datatypes; /* struct tr_datatype */
struct tr_list * outbuf_datatypes; /* struct tr_datatype */
struct event event_read;
struct event event_write;