Changes in / [08abd81:a613fea1] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/il/arp/arp.c

    r08abd81 ra613fea1  
    4040#include <mem.h>
    4141#include <fibril_synch.h>
    42 #include <assert.h>
    4342#include <stdio.h>
    4443#include <str.h>
     
    709708        bool retry = false;
    710709        int rc;
    711 
    712         assert(fibril_mutex_is_locked(&arp_globals.lock));
    713710       
    714711restart:
     
    728725        if (trans) {
    729726                if (trans->hw_addr) {
    730                         /* The translation is in place. */
    731727                        *translation = trans->hw_addr;
    732728                        return EOK;
     
    734730               
    735731                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 */
    747733                        arp_clear_trans(trans);
    748734                        arp_addr_exclude(&proto->addresses, target->value,
     
    751737                }
    752738               
    753                 /*
    754                  * We are a random passer-by who merely joins an already waiting
    755                  * fibril in waiting for the translation.
    756                  */
    757739                rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
    758740                    ARP_TRANS_WAIT);
     
    760742                        return ENOENT;
    761743               
    762                 /*
    763                  * Need to recheck because we did not hold the lock while
    764                  * sleeping on the condition variable.
    765                  */
    766744                retry = true;
    767745                goto restart;
     
    770748        if (retry)
    771749                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;
    786750       
    787751        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
     
    799763        }
    800764       
     765        rc = arp_send_request(device_id, protocol, target, device, proto);
     766        if (rc != EOK)
     767                return rc;
     768       
    801769        rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
    802770            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)
    811772                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       
    821774        retry = true;
    822775        goto restart;
Note: See TracChangeset for help on using the changeset viewer.