ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/StampedLock.java
(Generate patch)

Comparing jsr166/src/jsr166e/StampedLock.java (file contents):
Revision 1.30 by jsr166, Thu Jan 24 04:10:44 2013 UTC vs.
Revision 1.31 by dl, Thu Jan 24 21:35:03 2013 UTC

# Line 1033 | Line 1033 | public class StampedLock implements java
1033                      return cancelWaiter(node, null, false);
1034                  node.thread = Thread.currentThread();
1035                  if (node.prev == p && p.status == WAITING && // recheck
1036 <                    (p != whead || (state & ABITS) != 0L)) {
1036 >                    (p != whead || (state & ABITS) != 0L))
1037                      U.park(false, time);
1038                    if (interruptible && Thread.interrupted())
1039                        return cancelWaiter(node, null, true);
1040                }
1038                  node.thread = null;
1039 +                if (interruptible && Thread.interrupted())
1040 +                    return cancelWaiter(node, null, true);
1041              }
1042          }
1043      }
# Line 1101 | Line 1100 | public class StampedLock implements java
1100                                             node.cowait = p.cowait, node)) {
1101                      node.thread = Thread.currentThread();
1102                      for (long time;;) {
1103 +                        if (interruptible && Thread.interrupted())
1104 +                            return cancelWaiter(node, p, true);
1105                          if (deadline == 0L)
1106                              time = 0L;
1107                          else if ((time = deadline - System.nanoTime()) <= 0L)
# Line 1115 | Line 1116 | public class StampedLock implements java
1116                          if (node.thread == null) // must recheck
1117                              break;
1118                          U.park(false, time);
1118                        if (interruptible && Thread.interrupted())
1119                            return cancelWaiter(node, p, true);
1119                      }
1120                      group = p;
1121                  }
# Line 1174 | Line 1173 | public class StampedLock implements java
1173                      return cancelWaiter(node, null, false);
1174                  node.thread = Thread.currentThread();
1175                  if (node.prev == p && p.status == WAITING &&
1176 <                    (p != whead || (state & ABITS) != WBIT)) {
1176 >                    (p != whead || (state & ABITS) != WBIT))
1177                      U.park(false, time);
1179                    if (interruptible && Thread.interrupted())
1180                        return cancelWaiter(node, null, true);
1181                }
1178                  node.thread = null;
1179 +                if (interruptible && Thread.interrupted())
1180 +                    return cancelWaiter(node, null, true);
1181              }
1182          }
1183      }
1184  
1187    /**
1188     * If node non-null, forces cancel status and unsplices from queue
1189     * if possible. This is a variant of cancellation methods in
1190     * AbstractQueuedSynchronizer (see its detailed explanation in AQS
1191     * internal documentation) that more conservatively wakes up other
1192     * threads that may have had their links changed, so as to preserve
1193     * liveness in the main signalling methods.
1194     */
1195    private long cancelWaiter(WNode node, WNode group, boolean interrupted) {
1196        if (node != null) {
1197            node.thread = null;
1198            node.status = CANCELLED;
1199            if (group != null) {
1200                for (WNode p = group, q; p != null; p = q) {
1201                    if ((q = p.cowait) != null && q.status == CANCELLED) {
1202                        U.compareAndSwapObject(p, WCOWAIT, q, q.cowait);
1203                        break;
1204                    }
1205                }
1206            }
1207            else {
1208                for (WNode pred = node.prev; pred != null; ) {
1209                    WNode succ, pp; Thread w;
1210                    while ((succ = node.next) == null ||
1211                           succ.status == CANCELLED) {
1212                        WNode q = null;
1213                        for (WNode t = wtail; t != null && t != node; t = t.prev)
1214                            if (t.status != CANCELLED)
1215                                q = t;
1216                        if (succ == q ||
1217                            U.compareAndSwapObject(node, WNEXT,
1218                                                   succ, succ = q)) {
1219                            if (succ == null && node == wtail)
1220                                U.compareAndSwapObject(this, WTAIL, node, pred);
1221                            break;
1222                        }
1223                    }
1224                    if (pred.next == node)
1225                        U.compareAndSwapObject(pred, WNEXT, node, succ);
1226                    if (succ != null && (w = succ.thread) != null)
1227                        U.unpark(w);
1228                    if (pred.status != CANCELLED || (pp = pred.prev) == null)
1229                        break;
1230                    node.prev = pp; // repeat for new pred
1231                    U.compareAndSwapObject(pp, WNEXT, pred, succ);
1232                    pred = pp;
1233                }
1234            }
1235        }
1236        release(whead);
1237        return (interrupted || Thread.interrupted()) ? INTERRUPTED : 0L;
1238    }
1239
1240    // Unsafe mechanics
1241    private static final sun.misc.Unsafe U;
1242    private static final long STATE;
1243    private static final long WHEAD;
1244    private static final long WTAIL;
1245    private static final long WNEXT;
1246    private static final long WSTATUS;
1247    private static final long WCOWAIT;
1248
1249    static {
1250        try {
1251            U = getUnsafe();
1252            Class<?> k = StampedLock.class;
1253            Class<?> wk = WNode.class;
1254            STATE = U.objectFieldOffset
1255                (k.getDeclaredField("state"));
1256            WHEAD = U.objectFieldOffset
1257                (k.getDeclaredField("whead"));
1258            WTAIL = U.objectFieldOffset
1259                (k.getDeclaredField("wtail"));
1260            WSTATUS = U.objectFieldOffset
1261                (wk.getDeclaredField("status"));
1262            WNEXT = U.objectFieldOffset
1263                (wk.getDeclaredField("next"));
1264            WCOWAIT = U.objectFieldOffset
1265                (wk.getDeclaredField("cowait"));
1266
1267        } catch (Exception e) {
1268            throw new Error(e);
1269        }
1270    }
1271
1185      /**
1186       * Returns a sun.misc.Unsafe.  Suitable for use in a 3rd party package.
1187       * Replace with a simple call to Unsafe.getUnsafe when integrating

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines