Fixed bug with self loopback packets in multithreaded environments
This commit is contained in:
parent
bafbba4df8
commit
b577841d03
3 changed files with 27 additions and 4 deletions
|
@ -2567,7 +2567,7 @@ t_stat xq_attach(UNIT* uptr, char* cptr)
|
||||||
if (status != SCPE_OK) {
|
if (status != SCPE_OK) {
|
||||||
free(tptr);
|
free(tptr);
|
||||||
free(xq->var->etherface);
|
free(xq->var->etherface);
|
||||||
xq->var->etherface = 0;
|
xq->var->etherface = NULL;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
if (xq->var->poll == 0) {
|
if (xq->var->poll == 0) {
|
||||||
|
@ -2575,7 +2575,7 @@ t_stat xq_attach(UNIT* uptr, char* cptr)
|
||||||
if (status != SCPE_OK) {
|
if (status != SCPE_OK) {
|
||||||
free(tptr);
|
free(tptr);
|
||||||
free(xq->var->etherface);
|
free(xq->var->etherface);
|
||||||
xq->var->etherface = 0;
|
xq->var->etherface = NULL;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
xq->var->must_poll = 0;
|
xq->var->must_poll = 0;
|
||||||
|
@ -2589,6 +2589,8 @@ t_stat xq_attach(UNIT* uptr, char* cptr)
|
||||||
printf("%s: MAC Address Conflict on LAN for address %s, change the MAC address to a unique value\n", xq->dev->name, buf);
|
printf("%s: MAC Address Conflict on LAN for address %s, change the MAC address to a unique value\n", xq->dev->name, buf);
|
||||||
if (sim_log) fprintf (sim_log, "%s: MAC Address Conflict on LAN for address %s, change the MAC address to a unique value\n", xq->dev->name, buf);
|
if (sim_log) fprintf (sim_log, "%s: MAC Address Conflict on LAN for address %s, change the MAC address to a unique value\n", xq->dev->name, buf);
|
||||||
eth_close(xq->var->etherface);
|
eth_close(xq->var->etherface);
|
||||||
|
free(xq->var->etherface);
|
||||||
|
xq->var->etherface = NULL;
|
||||||
return SCPE_NOATT;
|
return SCPE_NOATT;
|
||||||
}
|
}
|
||||||
uptr->filename = tptr;
|
uptr->filename = tptr;
|
||||||
|
@ -2613,7 +2615,7 @@ t_stat xq_detach(UNIT* uptr)
|
||||||
if (uptr->flags & UNIT_ATT) {
|
if (uptr->flags & UNIT_ATT) {
|
||||||
eth_close (xq->var->etherface);
|
eth_close (xq->var->etherface);
|
||||||
free(xq->var->etherface);
|
free(xq->var->etherface);
|
||||||
xq->var->etherface = 0;
|
xq->var->etherface = NULL;
|
||||||
free(uptr->filename);
|
free(uptr->filename);
|
||||||
uptr->filename = NULL;
|
uptr->filename = NULL;
|
||||||
uptr->flags &= ~UNIT_ATT;
|
uptr->flags &= ~UNIT_ATT;
|
||||||
|
|
20
sim_ether.c
20
sim_ether.c
|
@ -151,6 +151,8 @@
|
||||||
|
|
||||||
Modification history:
|
Modification history:
|
||||||
|
|
||||||
|
18-Apr-11 MP Fixed race condition with self loopback packets in
|
||||||
|
multithreaded environments
|
||||||
09-Jan-11 MP Fixed missing crc data when USE_READER_THREAD is defined and
|
09-Jan-11 MP Fixed missing crc data when USE_READER_THREAD is defined and
|
||||||
crc's are needed (only the pdp11_xu)
|
crc's are needed (only the pdp11_xu)
|
||||||
16-Dec-10 MP added priority boost for read and write threads when
|
16-Dec-10 MP added priority boost for read and write threads when
|
||||||
|
@ -1444,6 +1446,7 @@ t_stat eth_open(ETH_DEV* dev, char* name, DEVICE* dptr, uint32 dbit)
|
||||||
ethq_init (&dev->read_queue, 200); /* initialize FIFO queue */
|
ethq_init (&dev->read_queue, 200); /* initialize FIFO queue */
|
||||||
pthread_mutex_init (&dev->lock, NULL);
|
pthread_mutex_init (&dev->lock, NULL);
|
||||||
pthread_mutex_init (&dev->writer_lock, NULL);
|
pthread_mutex_init (&dev->writer_lock, NULL);
|
||||||
|
pthread_mutex_init (&dev->self_lock, NULL);
|
||||||
pthread_cond_init (&dev->writer_cond, NULL);
|
pthread_cond_init (&dev->writer_cond, NULL);
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
|
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
|
||||||
|
@ -1495,6 +1498,7 @@ t_stat eth_close(ETH_DEV* dev)
|
||||||
pthread_mutex_destroy (&dev->lock);
|
pthread_mutex_destroy (&dev->lock);
|
||||||
pthread_cond_signal (&dev->writer_cond);
|
pthread_cond_signal (&dev->writer_cond);
|
||||||
pthread_join (dev->writer_thread, NULL);
|
pthread_join (dev->writer_thread, NULL);
|
||||||
|
pthread_mutex_destroy (&dev->self_lock);
|
||||||
pthread_mutex_destroy (&dev->writer_lock);
|
pthread_mutex_destroy (&dev->writer_lock);
|
||||||
pthread_cond_destroy (&dev->writer_cond);
|
pthread_cond_destroy (&dev->writer_cond);
|
||||||
if (1) {
|
if (1) {
|
||||||
|
@ -1534,8 +1538,10 @@ t_stat eth_check_address_conflict (ETH_DEV* dev,
|
||||||
ETH_PACK send, recv;
|
ETH_PACK send, recv;
|
||||||
t_stat status;
|
t_stat status;
|
||||||
int responses = 0;
|
int responses = 0;
|
||||||
|
char mac_string[32];
|
||||||
|
|
||||||
sim_debug(dev->dbit, dev->dptr, "Determining Address Conflict...\n");
|
eth_mac_fmt(mac, mac_string);
|
||||||
|
sim_debug(dev->dbit, dev->dptr, "Determining Address Conflict for MAC address: %s\n", mac_string);
|
||||||
|
|
||||||
/* build a loopback forward request packet */
|
/* build a loopback forward request packet */
|
||||||
memset (&send, 0, sizeof(ETH_PACK));
|
memset (&send, 0, sizeof(ETH_PACK));
|
||||||
|
@ -1617,8 +1623,14 @@ t_stat _eth_write(ETH_DEV* dev, ETH_PACK* packet, ETH_PCALLBACK routine)
|
||||||
|
|
||||||
/* detect sending of loopback packet */
|
/* detect sending of loopback packet */
|
||||||
if ((status == 0) && (LOOPBACK_SELF_FRAME(dev->physical_addr, packet->msg))) {
|
if ((status == 0) && (LOOPBACK_SELF_FRAME(dev->physical_addr, packet->msg))) {
|
||||||
|
#ifdef USE_READER_THREAD
|
||||||
|
pthread_mutex_lock (&dev->self_lock);
|
||||||
|
#endif
|
||||||
dev->loopback_self_sent += dev->reflections;
|
dev->loopback_self_sent += dev->reflections;
|
||||||
dev->loopback_self_sent_total++;
|
dev->loopback_self_sent_total++;
|
||||||
|
#ifdef USE_READER_THREAD
|
||||||
|
pthread_mutex_unlock (&dev->self_lock);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* if packet->len */
|
} /* if packet->len */
|
||||||
|
@ -2122,6 +2134,9 @@ _eth_callback(u_char* info, const struct pcap_pkthdr* header, const u_char* data
|
||||||
|
|
||||||
/* detect reception of loopback packet to our physical address */
|
/* detect reception of loopback packet to our physical address */
|
||||||
if (LOOPBACK_SELF_FRAME(dev->physical_addr, data)) {
|
if (LOOPBACK_SELF_FRAME(dev->physical_addr, data)) {
|
||||||
|
#ifdef USE_READER_THREAD
|
||||||
|
pthread_mutex_lock (&dev->self_lock);
|
||||||
|
#endif
|
||||||
dev->loopback_self_rcvd_total++;
|
dev->loopback_self_rcvd_total++;
|
||||||
/* lower reflection count - if already zero, pass it on */
|
/* lower reflection count - if already zero, pass it on */
|
||||||
if (dev->loopback_self_sent > 0) {
|
if (dev->loopback_self_sent > 0) {
|
||||||
|
@ -2132,6 +2147,9 @@ _eth_callback(u_char* info, const struct pcap_pkthdr* header, const u_char* data
|
||||||
#ifndef USE_BPF
|
#ifndef USE_BPF
|
||||||
else
|
else
|
||||||
from_me = 0;
|
from_me = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_READER_THREAD
|
||||||
|
pthread_mutex_unlock (&dev->self_lock);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
Modification history:
|
Modification history:
|
||||||
|
|
||||||
|
18-Apr-11 MP Fixed race condition with self loopback packets in
|
||||||
|
multithreaded environments
|
||||||
09-Dec-10 MP Added support to determine if network address conflicts exist
|
09-Dec-10 MP Added support to determine if network address conflicts exist
|
||||||
07-Dec-10 MP Reworked DECnet self detection to the more general approach
|
07-Dec-10 MP Reworked DECnet self detection to the more general approach
|
||||||
of loopback self when any Physical Address is being set.
|
of loopback self when any Physical Address is being set.
|
||||||
|
@ -203,6 +205,7 @@ struct eth_device {
|
||||||
pthread_t reader_thread; /* Reader Thread Id */
|
pthread_t reader_thread; /* Reader Thread Id */
|
||||||
pthread_t writer_thread; /* Writer Thread Id */
|
pthread_t writer_thread; /* Writer Thread Id */
|
||||||
pthread_mutex_t writer_lock;
|
pthread_mutex_t writer_lock;
|
||||||
|
pthread_mutex_t self_lock;
|
||||||
pthread_cond_t writer_cond;
|
pthread_cond_t writer_cond;
|
||||||
struct write_request {
|
struct write_request {
|
||||||
struct write_request *next;
|
struct write_request *next;
|
||||||
|
|
Loading…
Add table
Reference in a new issue