00001 package cast.core;
00002
00003 import java.util.HashMap;
00004 import java.util.concurrent.Semaphore;
00005
00006 import cast.cdl.WorkingMemoryPermissions;
00007 import cast.core.CASTUtils;
00008
00016 public class CASTWMPermissionMap {
00017
00024 private static class PermissionsStruct {
00025 WorkingMemoryPermissions m_permissions;
00026 Semaphore m_mutex;
00027 String m_owner;
00028 int m_lockCount;
00029 boolean m_scheduledForDeletion;
00030
00031 public PermissionsStruct(WorkingMemoryPermissions _permissions,
00032 Semaphore _mutex, String _owner, int _lockCount,
00033 boolean _scheduledForDeletion) {
00034 super();
00035 m_permissions = _permissions;
00036 m_mutex = _mutex;
00037 m_owner = _owner;
00038 m_lockCount = _lockCount;
00039 m_scheduledForDeletion = _scheduledForDeletion;
00040 }
00041
00042 };
00043
00044 private final HashMap<String, PermissionsStruct> m_permissions;
00045
00046 private final Semaphore m_access;
00047
00048 public CASTWMPermissionMap() {
00049 m_permissions = new HashMap<String, PermissionsStruct>();
00050 m_access = new Semaphore(1);
00051 }
00052
00053 private final void lockMap() {
00054 try {
00055 m_access.acquire();
00056 }
00057 catch (InterruptedException e) {
00058 e.printStackTrace();
00059 }
00060 }
00061
00062 private final void unlockMap() {
00063 m_access.release();
00064 }
00065
00071 public void add(String _id) {
00072 lockMap();
00073 assert (!m_permissions.containsKey(_id));
00074 m_permissions.put(_id, new PermissionsStruct(
00075 WorkingMemoryPermissions.UNLOCKED, new Semaphore(1), "", 0,
00076 false));
00077 unlockMap();
00078 }
00086 public void lock(String _id, String _component,
00087 WorkingMemoryPermissions _permission) throws InterruptedException {
00088
00089 Semaphore mutex = null;
00090
00091 lockMap();
00092
00093 if (!live(_id)) {
00094 unlockMap();
00095 return;
00096 }
00097
00098 PermissionsStruct ps = m_permissions.get(_id);
00099
00100 assert (ps != null);
00101
00102 if (ps.m_owner.equals(_component)) {
00103 assert (_permission == ps.m_permissions);
00104 assert (ps.m_lockCount > 0);
00105 ps.m_lockCount++;
00106 unlockMap();
00107 return;
00108 }
00109
00110 mutex = ps.m_mutex;
00111
00112 unlockMap();
00113
00114
00115 mutex.acquire();
00116
00117 lockMap();
00118
00119 if (!live(_id)) {
00120 assert (mutex != null);
00121 mutex.release();
00122 }
00123 else {
00124 ps = m_permissions.get(_id);
00125 ps.m_permissions = _permission;
00126 ps.m_owner = _component;
00127 ps.m_lockCount = 1;
00128 ps.m_scheduledForDeletion = false;
00129 assert (m_permissions.get(_id).m_owner.equals(_component));
00130 assert (m_permissions.get(_id).m_permissions.equals(_permission));
00131 }
00132 unlockMap();
00133
00134 }
00135
00136 private boolean live(String _id) {
00137 PermissionsStruct ps = m_permissions.get(_id);
00138 if (ps != null && !ps.m_scheduledForDeletion) {
00139 return true;
00140 }
00141 else {
00142 return false;
00143 }
00144
00145 }
00146
00152 public void unlock(String _id, String _component) {
00153 lockMap();
00154 PermissionsStruct ps = m_permissions.get(_id);
00155 if (ps == null) {
00156
00157
00158 }
00159 else if (ps.m_lockCount == 0) {
00160
00161
00162 }
00163 else if (ps.m_lockCount > 1) {
00164 assert (ps.m_owner.equals(_component));
00165
00166
00167 ps.m_lockCount--;
00168 }
00169 else {
00170 if (!CASTUtils.deleteAllowed(ps.m_permissions)) {
00171 assert (ps.m_owner.equals(_component));
00172 }
00173 ps.m_permissions = WorkingMemoryPermissions.UNLOCKED;
00174 ps.m_owner = "";
00175 ps.m_lockCount = 0;
00176 ps.m_mutex.release();
00177 }
00178 unlockMap();
00179 }
00180
00188 public boolean tryLock(String _id, String _component,
00189 WorkingMemoryPermissions _permission) throws InterruptedException {
00190
00191 boolean ret = false;
00192
00193 lockMap();
00194 PermissionsStruct ps = m_permissions.get(_id);
00195
00196
00197 if (ps == null || ps.m_scheduledForDeletion) {
00198 ret = false;
00199 }
00200
00201 else if (ps.m_lockCount > 0 && !(ps.m_owner.equals(_component))) {
00202 ret = false;
00203 }
00204
00205 else {
00206
00207 if (ps.m_lockCount > 0) {
00208 assert (ps.m_permissions == _permission);
00209 ps.m_lockCount++;
00210
00211
00212
00213 }
00214
00215 else {
00216
00217
00218
00219 System.out.println("CASTWMPermissionMap.tryLock()");
00220 ps.m_mutex.acquire();
00221 ps.m_permissions = _permission;
00222 ps.m_owner = _component;
00223 ps.m_lockCount = 1;
00224 ps.m_scheduledForDeletion = false;
00225 }
00226 ret = true;
00227 }
00228
00229 unlockMap();
00230 return ret;
00231 }
00232
00239 public boolean isLocked(String _id) {
00240 boolean ret = false;
00241 lockMap();
00242 PermissionsStruct ps = m_permissions.get(_id);
00243
00244 if (ps != null) {
00245 ret = ps.m_lockCount > 0;
00246 }
00247 unlockMap();
00248 return ret;
00249 }
00250
00257 public boolean isLockHolder(String _id, String _component) {
00258 boolean ret = false;
00259 lockMap();
00260 PermissionsStruct ps = m_permissions.get(_id);
00261 if (ps != null) {
00262 ret = (_component.equals(ps.m_owner));
00263 }
00264 unlockMap();
00265 return ret;
00266 }
00267
00268 public boolean contains(String _id) {
00269
00270 boolean ret = false;
00271 lockMap();
00272 PermissionsStruct ps = m_permissions.get(_id);
00273
00274
00275 if (ps != null) {
00276 ret = !(ps.m_scheduledForDeletion);
00277 }
00278 unlockMap();
00279 return ret;
00280 }
00281
00288 public WorkingMemoryPermissions getPermissions(String _id) {
00289 lockMap();
00290 PermissionsStruct ps = m_permissions.get(_id);
00291 WorkingMemoryPermissions perm = null;
00292 if (ps == null || ps.m_scheduledForDeletion) {
00293
00294
00295
00296 perm = WorkingMemoryPermissions.DOESNOTEXIST;
00297 }
00298 else {
00299 perm = ps.m_permissions;
00300 }
00301 unlockMap();
00302 return perm;
00303 }
00304
00305 public void remove(String _id) throws InterruptedException {
00306
00307 PermissionsStruct ps = null;
00308 Semaphore mutex = null;
00309 lockMap();
00310
00311 ps = m_permissions.get(_id);
00312
00313 if (ps == null) {
00314
00315
00316 unlockMap();
00317 return;
00318 }
00319
00320 else if (ps.m_lockCount == 0) {
00321 m_permissions.remove(_id);
00322 unlockMap();
00323 return;
00324 }
00325
00326 else {
00327 ps.m_scheduledForDeletion = true;
00328 }
00329
00330
00331
00332 mutex = ps.m_mutex;
00333
00334 while (ps.m_lockCount > 0) {
00335
00336
00337 unlockMap();
00338
00339
00340 mutex.acquire();
00341
00342
00343 lockMap();
00344
00345 mutex.release();
00346
00347 ps = m_permissions.get(_id);
00348
00349 }
00350
00351
00352
00353 m_permissions.remove(_id);
00354 unlockMap();
00355 }
00356
00357 public String getLockHolder(String _id) {
00358 lockMap();
00359 PermissionsStruct ps = m_permissions.get(_id);
00360 assert (ps != null);
00361 String owner = ps.m_owner;
00362 unlockMap();
00363 return owner;
00364 }
00365 }