struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br, unsigned char *addr) { struct net_bridge_fdb_entry *fdb; read_lock_bh(&br->hash_lock); fdb = br->hash[br_mac_hash(addr)]; while (fdb != NULL) { if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) { if (!has_expired(br, fdb)) { atomic_inc(&fdb->use_count); read_unlock_bh(&br->hash_lock); return fdb; } read_unlock_bh(&br->hash_lock); return NULL; } fdb = fdb->next_hash; } read_unlock_bh(&br->hash_lock); return NULL; }
NTSTATUS thread_impl_t::wait_on_handles( ULONG count, PHANDLE handles, WAIT_TYPE type, BOOLEAN alert, PLARGE_INTEGER timeout) { NTSTATUS r = STATUS_SUCCESS; Alertable = alert; WaitType = type; // iterate the array and wait on each handle for (ULONG i=0; i<count; i++) { dprintf("handle[%ld] = %08lx\n", i, (ULONG) handles[i]); object_t *any = 0; r = object_from_handle( any, handles[i], SYNCHRONIZE ); if (r < STATUS_SUCCESS) { end_wait(); return r; } sync_object_t *obj = dynamic_cast<sync_object_t*>( any ); if (!obj) { end_wait(); return STATUS_INVALID_HANDLE; } r = wait_on( obj ); if (r < STATUS_SUCCESS) { end_wait(); return r; } } // make sure we wait for a little bit every time LARGE_INTEGER t; if (timeout && timeout->QuadPart <= 0 && timeout->QuadPart> -100000LL) { t.QuadPart = -100000LL; timeout = &t; } set_timeout( timeout ); while (1) { r = check_wait(); if (r != STATUS_PENDING) break; if (alerted) { alerted = FALSE; r = STATUS_ALERTED; break; } if (timeout && has_expired()) { r = STATUS_TIMEOUT; break; } in_wait = TRUE; wait(); assert( in_wait == FALSE ); } end_wait(); set_timeout( 0 ); return r; }
int br_fdb_get_entries(struct net_bridge *br, unsigned char *_buf, int maxnum, int offset) { int i; int num; struct __fdb_entry *walk; num = 0; walk = (struct __fdb_entry *)_buf; read_lock_bh(&br->hash_lock); for (i=0;i<BR_HASH_SIZE;i++) { struct net_bridge_fdb_entry *f; f = br->hash[i]; while (f != NULL && num < maxnum) { struct __fdb_entry ent; int err; struct net_bridge_fdb_entry *g; struct net_bridge_fdb_entry **pp; if (has_expired(br, f)) { f = f->next_hash; continue; } if (offset) { offset--; f = f->next_hash; continue; } copy_fdb(&ent, f); atomic_inc(&f->use_count); read_unlock_bh(&br->hash_lock); err = copy_to_user(walk, &ent, sizeof(struct __fdb_entry)); read_lock_bh(&br->hash_lock); g = f->next_hash; pp = f->pprev_hash; br_fdb_put(f); if (err) goto out_fault; if (g == NULL && pp == NULL) goto out_disappeared; num++; walk++; f = g; } } out: read_unlock_bh(&br->hash_lock); return num; out_disappeared: num = -EAGAIN; goto out; out_fault: num = -EFAULT; goto out; }