Changes in / [08abd81:a613fea1] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/arp/arp.c
r08abd81 ra613fea1 40 40 #include <mem.h> 41 41 #include <fibril_synch.h> 42 #include <assert.h>43 42 #include <stdio.h> 44 43 #include <str.h> … … 709 708 bool retry = false; 710 709 int rc; 711 712 assert(fibril_mutex_is_locked(&arp_globals.lock));713 710 714 711 restart: … … 728 725 if (trans) { 729 726 if (trans->hw_addr) { 730 /* The translation is in place. */731 727 *translation = trans->hw_addr; 732 728 return EOK; … … 734 730 735 731 if (retry) { 736 /* 737 * We may get here as a result of being signalled for 738 * some reason while waiting for the translation (e.g. 739 * translation becoming available, record being removed 740 * from the table) and then losing the race for 741 * the arp_globals.lock with someone else who modified 742 * the table. 743 * 744 * Remove the incomplete record so that it is possible 745 * to make new ARP requests. 746 */ 732 /* Remove the translation from the map */ 747 733 arp_clear_trans(trans); 748 734 arp_addr_exclude(&proto->addresses, target->value, … … 751 737 } 752 738 753 /*754 * We are a random passer-by who merely joins an already waiting755 * fibril in waiting for the translation.756 */757 739 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 758 740 ARP_TRANS_WAIT); … … 760 742 return ENOENT; 761 743 762 /*763 * Need to recheck because we did not hold the lock while764 * sleeping on the condition variable.765 */766 744 retry = true; 767 745 goto restart; … … 770 748 if (retry) 771 749 return EAGAIN; 772 773 /*774 * We are under the protection of arp_globals.lock, so we can afford to775 * first send the ARP request and then insert an incomplete ARP record.776 * The incomplete record is used to tell any other potential waiter777 * that this fibril has already sent the request and that it is waiting778 * for the answer. Lastly, any fibril which sees the incomplete request779 * can perform a timed wait on its condition variable to wait for the780 * ARP reply to arrive.781 */782 783 rc = arp_send_request(device_id, protocol, target, device, proto);784 if (rc != EOK)785 return rc;786 750 787 751 trans = (arp_trans_t *) malloc(sizeof(arp_trans_t)); … … 799 763 } 800 764 765 rc = arp_send_request(device_id, protocol, target, device, proto); 766 if (rc != EOK) 767 return rc; 768 801 769 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 802 770 ARP_TRANS_WAIT); 803 if (rc == ETIMEOUT) { 804 /* 805 * Remove the incomplete record so that it is possible to make 806 * new ARP requests. 807 */ 808 arp_clear_trans(trans); 809 arp_addr_exclude(&proto->addresses, target->value, 810 target->length); 771 if (rc == ETIMEOUT) 811 772 return ENOENT; 812 } 813 814 /* 815 * We need to recheck that the translation has indeed become available, 816 * because we dropped the arp_globals.lock while sleeping on the 817 * condition variable and someone else might have e.g. removed the 818 * translation before we managed to lock arp_globals.lock again. 819 */ 820 773 821 774 retry = true; 822 775 goto restart;
Note:
See TracChangeset
for help on using the changeset viewer.