/** * Remove the given bundle from the list. Returns true if the bundle was successfully removed, * false otherwise. * * @param free whether to free the bundle. This freeing will remove Bundle from storage including * its payload */ public boolean erase(Bundle bundle, boolean free) { if (bundle == null) { return false; } lock_.lock(); // "Now we need to take the bundle lock in order to search through // its mappings" [DTN2] bundle.get_lock().lock(); try { int pos = list_.indexOf(bundle); if (pos == -1) return false; Bundle b = del_bundle(pos, free); assert (b == bundle); return true; } catch (BundleListLockNotHoldByCurrentThread e) { Log.e(TAG, e.getMessage()); return false; } finally { bundle.get_lock().unlock(); lock_.unlock(); } }
/** * "Helper routine to add a bundle at the indicated position." [DTN2] * * @throws BundleLockNotHeldByCurrentThread * @throws InterruptedException */ private void add_bundle(final Bundle b, final int pos) throws BundleListLockNotHoldByCurrentThread, BundleLockNotHeldByCurrentThread, InterruptedException { if (!lock_.isHeldByCurrentThread()) throw new BundleListLockNotHoldByCurrentThread(); if (!b.get_lock().isHeldByCurrentThread()) throw new BundleLockNotHeldByCurrentThread(); if (b.is_queued_on(this)) { Log.e( TAG, String.format( "ERROR in add bundle: " + "bundle id %d already on list [%s]", b.bundleid(), name_)); return; } list_.add(pos, b); b.mappings().add(this); Log.d( TAG, String.format( "bundle id %d is added to list [%s] , the size become", b.bundleid(), name_, list_.size())); }
/** Add a new bundle to the front of the list. */ public boolean push_front(Bundle bundle) { lock_.lock(); bundle.get_lock().lock(); try { add_bundle(bundle, 0); return true; } catch (BundleLockNotHeldByCurrentThread e) { Log.e(TAG, e.getMessage()); } catch (InterruptedException e) { Log.e(TAG, e.getMessage()); } catch (BundleListLockNotHoldByCurrentThread e) { Log.e(TAG, e.getMessage()); } finally { bundle.get_lock().unlock(); lock_.unlock(); } return true; }
/** Insert the given bundle sorted by the given sort method. */ public boolean insert_sorted(Bundle bundle, Comparator<Bundle> sort_comparator) { lock_.lock(); bundle.get_lock().lock(); try { add_bundle(bundle, list_.size()); Collections.sort(this.list_, sort_comparator); return true; } catch (BundleLockNotHeldByCurrentThread e) { Log.e(TAG, e.getMessage()); return false; } catch (InterruptedException e) { Log.e(TAG, e.getMessage()); return false; } catch (BundleListLockNotHoldByCurrentThread e) { Log.e(TAG, e.getMessage()); return false; } finally { bundle.get_lock().unlock(); lock_.unlock(); } }
/** * Helper routine to remove a bundle from the indicated position. This is called by other public * functions such as pop_front This is the function will actually post the bundle free event to * the Bundle daemon * * @param pos Position to delete a flag indicate whether to free the bundle as well * @param free whether to free the bundle. This freeing will remove Bundle from storage including * its payload * @throws BundleListLockNotHoldByCurrentThread * @returns the bundle that, before this call, was at the position */ private Bundle del_bundle(final int pos, boolean free) throws BundleListLockNotHoldByCurrentThread { Bundle b = list_.get(pos); assert (lock_.isHeldByCurrentThread()); if (!lock_.isHeldByCurrentThread()) throw new BundleListLockNotHoldByCurrentThread(); b.get_lock().lock(); try { Log.d( TAG, String.format("bundle id %d del_bundle: deleting mapping [%s]", b.bundleid(), name_)); if (!b.mappings().contains(this)) { Log.e( TAG, String.format( "ERROR in del bundle: " + "bundle id %d has no mapping for list [%s]", b.bundleid(), name_)); } else { b.mappings().remove(this); } // "remove the bundle from the list" [DTN2] list_.remove(b); if (free) BundleDaemon.getInstance().post(new BundleFreeEvent(b)); return b; } catch (BundleLockNotHeldByCurrentThread e) { Log.e(TAG, e.getMessage()); return null; } finally { b.get_lock().unlock(); } }