Changeset 87e373b in mainline
- Timestamp:
- 2011-01-13T21:18:25Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 08abd81, c4fb95d3
- Parents:
- 80cd7cd
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/arp/arp.c
r80cd7cd r87e373b 40 40 #include <mem.h> 41 41 #include <fibril_synch.h> 42 #include <assert.h> 42 43 #include <stdio.h> 43 44 #include <str.h> … … 708 709 bool retry = false; 709 710 int rc; 711 712 assert(fibril_mutex_is_locked(&arp_globals.lock)); 710 713 711 714 restart: … … 725 728 if (trans) { 726 729 if (trans->hw_addr) { 730 /* The translation is in place. */ 727 731 *translation = trans->hw_addr; 728 732 return EOK; … … 730 734 731 735 if (retry) { 732 /* Remove the translation from the map */ 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 */ 733 747 arp_clear_trans(trans); 734 748 arp_addr_exclude(&proto->addresses, target->value, … … 737 751 } 738 752 753 /* 754 * We are a random passer-by who merely joins an already waiting 755 * fibril in waiting for the translation. 756 */ 739 757 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 740 758 ARP_TRANS_WAIT); … … 742 760 return ENOENT; 743 761 762 /* 763 * Need to recheck because we did not hold the lock while 764 * sleeping on the condition variable. 765 */ 744 766 retry = true; 745 767 goto restart; … … 748 770 if (retry) 749 771 return EAGAIN; 772 773 /* 774 * We are under the protection of arp_globals.lock, so we can afford to 775 * first send the ARP request and then insert an incomplete ARP record. 776 * The incomplete record is used to tell any other potential waiter 777 * that this fibril has already sent the request and that it is waiting 778 * for the answer. Lastly, any fibril which sees the incomplete request 779 * can perform a timed wait on its condition variable to wait for the 780 * ARP reply to arrive. 781 */ 782 783 rc = arp_send_request(device_id, protocol, target, device, proto); 784 if (rc != EOK) 785 return rc; 750 786 751 787 trans = (arp_trans_t *) malloc(sizeof(arp_trans_t)); … … 763 799 } 764 800 765 rc = arp_send_request(device_id, protocol, target, device, proto);766 if (rc != EOK)767 return rc;768 769 801 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 770 802 ARP_TRANS_WAIT); 771 if (rc == ETIMEOUT) 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); 772 811 return ENOENT; 773 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 774 821 retry = true; 775 822 goto restart;
Note:
See TracChangeset
for help on using the changeset viewer.