diff --git a/PDP11/pdp11_xq.c b/PDP11/pdp11_xq.c index 89591bad..d871d66b 100644 --- a/PDP11/pdp11_xq.c +++ b/PDP11/pdp11_xq.c @@ -2567,7 +2567,7 @@ t_stat xq_attach(UNIT* uptr, char* cptr) if (status != SCPE_OK) { free(tptr); free(xq->var->etherface); - xq->var->etherface = 0; + xq->var->etherface = NULL; return status; } if (xq->var->poll == 0) { @@ -2575,7 +2575,7 @@ t_stat xq_attach(UNIT* uptr, char* cptr) if (status != SCPE_OK) { free(tptr); free(xq->var->etherface); - xq->var->etherface = 0; + xq->var->etherface = NULL; return status; } 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); 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); + free(xq->var->etherface); + xq->var->etherface = NULL; return SCPE_NOATT; } uptr->filename = tptr; @@ -2613,7 +2615,7 @@ t_stat xq_detach(UNIT* uptr) if (uptr->flags & UNIT_ATT) { eth_close (xq->var->etherface); free(xq->var->etherface); - xq->var->etherface = 0; + xq->var->etherface = NULL; free(uptr->filename); uptr->filename = NULL; uptr->flags &= ~UNIT_ATT; diff --git a/sim_ether.c b/sim_ether.c index feb04995..50fe7925 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -151,6 +151,8 @@ 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 crc's are needed (only the pdp11_xu) 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 */ pthread_mutex_init (&dev->lock, NULL); pthread_mutex_init (&dev->writer_lock, NULL); + pthread_mutex_init (&dev->self_lock, NULL); pthread_cond_init (&dev->writer_cond, NULL); pthread_attr_init(&attr); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); @@ -1495,6 +1498,7 @@ t_stat eth_close(ETH_DEV* dev) pthread_mutex_destroy (&dev->lock); pthread_cond_signal (&dev->writer_cond); pthread_join (dev->writer_thread, NULL); + pthread_mutex_destroy (&dev->self_lock); pthread_mutex_destroy (&dev->writer_lock); pthread_cond_destroy (&dev->writer_cond); if (1) { @@ -1534,8 +1538,10 @@ t_stat eth_check_address_conflict (ETH_DEV* dev, ETH_PACK send, recv; t_stat status; 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 */ 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 */ 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_total++; +#ifdef USE_READER_THREAD + pthread_mutex_unlock (&dev->self_lock); +#endif } } /* 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 */ if (LOOPBACK_SELF_FRAME(dev->physical_addr, data)) { +#ifdef USE_READER_THREAD + pthread_mutex_lock (&dev->self_lock); +#endif dev->loopback_self_rcvd_total++; /* lower reflection count - if already zero, pass it on */ 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 else from_me = 0; +#endif +#ifdef USE_READER_THREAD + pthread_mutex_unlock (&dev->self_lock); #endif } diff --git a/sim_ether.h b/sim_ether.h index 4374f31e..c9817788 100644 --- a/sim_ether.h +++ b/sim_ether.h @@ -28,6 +28,8 @@ 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 07-Dec-10 MP Reworked DECnet self detection to the more general approach 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 writer_thread; /* Writer Thread Id */ pthread_mutex_t writer_lock; + pthread_mutex_t self_lock; pthread_cond_t writer_cond; struct write_request { struct write_request *next;