1.1 --- a/dew4nb/src/org/netbeans/modules/dew4nb/services/debugger/ActiveSessions.java Thu Jan 30 17:12:55 2014 +0100
1.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/debugger/ActiveSessions.java Thu Jan 30 19:12:26 2014 +0100
1.3 @@ -50,15 +50,22 @@
1.4 import java.util.List;
1.5 import java.util.concurrent.ConcurrentHashMap;
1.6 import java.util.concurrent.ConcurrentMap;
1.7 +import java.util.concurrent.TimeUnit;
1.8 import java.util.concurrent.atomic.AtomicInteger;
1.9 +import java.util.concurrent.locks.Condition;
1.10 +import java.util.concurrent.locks.Lock;
1.11 +import java.util.concurrent.locks.ReentrantLock;
1.12 import java.util.logging.Level;
1.13 import java.util.logging.Logger;
1.14 import org.netbeans.api.annotations.common.CheckForNull;
1.15 import org.netbeans.api.annotations.common.NonNull;
1.16 import org.netbeans.api.annotations.common.NullAllowed;
1.17 import org.netbeans.api.debugger.DebuggerManager;
1.18 +import org.netbeans.api.debugger.DebuggerManagerAdapter;
1.19 +import org.netbeans.api.debugger.DebuggerManagerListener;
1.20 import org.netbeans.api.debugger.Session;
1.21 import org.netbeans.api.debugger.jpda.CallStackFrame;
1.22 +import org.netbeans.api.debugger.jpda.DebuggerStartException;
1.23 import org.netbeans.api.debugger.jpda.JPDADebugger;
1.24 import org.netbeans.api.debugger.jpda.JPDAThread;
1.25 import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl;
1.26 @@ -69,6 +76,7 @@
1.27 import org.openide.filesystems.FileObject;
1.28 import org.openide.filesystems.FileUtil;
1.29 import org.openide.filesystems.URLMapper;
1.30 +import org.openide.util.Exceptions;
1.31 import org.openide.util.Lookup;
1.32 import org.openide.util.Parameters;
1.33
1.34 @@ -98,18 +106,22 @@
1.35 Parameters.notNull("context", context); //NOI18N
1.36 Parameters.notNull("env", env); //NOI18N
1.37 final int id = sequencer.incrementAndGet();
1.38 - for (int i = 0; i < 10; i++) {
1.39 - final Session session = DebuggerManager.getDebuggerManager().getCurrentSession();
1.40 - if (session != null) {
1.41 - if (active.putIfAbsent(id, new Data(id, context, env, session)) != null) {
1.42 - throw new IllegalStateException("Trying to reuse active session"); //NOI18N
1.43 - }
1.44 - return id;
1.45 + final Session session = findSession();
1.46 + if (session != null) {
1.47 + if (active.putIfAbsent(id, new Data(id, context, env, session)) != null) {
1.48 + throw new IllegalStateException("Trying to reuse active session"); //NOI18N
1.49 + }
1.50 + final JPDADebugger jpda = session.lookupFirst(null, JPDADebugger.class);
1.51 + if (!(jpda instanceof JPDADebuggerImpl)) {
1.52 + throw new IllegalStateException("Wrong debugger service."); //NOI18N
1.53 }
1.54 try {
1.55 - Thread.sleep(2000);
1.56 - } catch (InterruptedException ex) {}
1.57 - }
1.58 + jpda.waitRunning();
1.59 + } catch (DebuggerStartException ex) {
1.60 + return -1;
1.61 + }
1.62 + return id;
1.63 + }
1.64 return -1;
1.65 }
1.66
1.67 @@ -140,6 +152,24 @@
1.68 return instance;
1.69 }
1.70
1.71 + /**
1.72 + * Finds debuggers session.
1.73 + * Todo: debugger API does not pair sessions with projects,
1.74 + * no way to find out correct session.
1.75 + * @return
1.76 + */
1.77 + @CheckForNull
1.78 + private Session findSession () {
1.79 + final DebuggerManager dm = DebuggerManager.getDebuggerManager();
1.80 + final DML dml = new DML(dm);
1.81 + dm.addDebuggerListener(dml);
1.82 + try {
1.83 + return dml.getCurrentSession();
1.84 + }finally {
1.85 + dm.removeDebuggerListener(dml);
1.86 + }
1.87 + }
1.88 +
1.89 private static final class Data implements PropertyChangeListener {
1.90 final int id;
1.91 final WorkspaceResolver.Context ctx;
1.92 @@ -273,4 +303,52 @@
1.93 }
1.94 }
1.95
1.96 + private static final class DML extends DebuggerManagerAdapter {
1.97 +
1.98 + private final DebuggerManager dm;
1.99 + private final Lock lock;
1.100 + private final Condition cond;
1.101 + //GuardedBy("lock")
1.102 + private Session session;
1.103 +
1.104 + DML(@NonNull final DebuggerManager dm) {
1.105 + Parameters.notNull("dm", dm); //NOI18N
1.106 + this.dm = dm;
1.107 + this.lock = new ReentrantLock();
1.108 + this.cond = lock.newCondition();
1.109 + }
1.110 +
1.111 + @Override
1.112 + public void sessionAdded(@NonNull Session session) {
1.113 + lock.lock();
1.114 + try {
1.115 + this.session = session;
1.116 + cond.signalAll();
1.117 + } finally {
1.118 + lock.unlock();
1.119 + }
1.120 + }
1.121 +
1.122 + Session getCurrentSession() {
1.123 + Session res = dm.getCurrentSession();
1.124 + if (res != null) {
1.125 + return res;
1.126 + }
1.127 + lock.lock();
1.128 + try {
1.129 + while (this.session == null) {
1.130 + try {
1.131 + if (!cond.await(20, TimeUnit.SECONDS)) {
1.132 + break;
1.133 + }
1.134 + } catch (InterruptedException e) {
1.135 + return null;
1.136 + }
1.137 + }
1.138 + return this.session;
1.139 + } finally {
1.140 + lock.unlock();
1.141 + }
1.142 + }
1.143 + }
1.144 }
1.145 \ No newline at end of file
2.1 --- a/dew4nb/src/org/netbeans/modules/dew4nb/services/debugger/AttachHandler.java Thu Jan 30 17:12:55 2014 +0100
2.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/debugger/AttachHandler.java Thu Jan 30 19:12:26 2014 +0100
2.3 @@ -42,6 +42,7 @@
2.4
2.5 package org.netbeans.modules.dew4nb.services.debugger;
2.6
2.7 +import java.util.concurrent.Executor;
2.8 import org.netbeans.api.annotations.common.NonNull;
2.9 import org.netbeans.modules.dew4nb.endpoint.AsyncRequestHandler;
2.10 import org.netbeans.modules.dew4nb.endpoint.EndPoint;
2.11 @@ -49,6 +50,7 @@
2.12 import org.netbeans.modules.dew4nb.endpoint.Status;
2.13 import org.netbeans.modules.dew4nb.spi.WorkspaceResolver;
2.14 import org.openide.filesystems.FileObject;
2.15 +import org.openide.util.RequestProcessor;
2.16 import org.openide.util.lookup.ServiceProvider;
2.17
2.18 /**
2.19 @@ -58,6 +60,7 @@
2.20 @ServiceProvider(service = RequestHandler.class)
2.21 public class AttachHandler extends AsyncRequestHandler<DebugAction, DebugMessageType> {
2.22
2.23 + private static final Executor WORKER = new RequestProcessor(AttachHandler.class);
2.24
2.25 public AttachHandler() {
2.26 super(DebugerModels.END_POINT, DebugMessageType.attach, DebugAction.class);
2.27 @@ -87,21 +90,25 @@
2.28 ctx.getWorkspace(),
2.29 "" //NOI18N
2.30 );
2.31 - Status status = Status.not_found;
2.32 - int id = -1;
2.33 + Status status = Status.not_found;
2.34 final FileObject workspace = resolver.resolveFile(serverCtx);
2.35 if (workspace != null) {
2.36 - id = ActiveSessions.getInstance().createSession(serverCtx, env);
2.37 + status = Status.accepted;
2.38 + WORKER.execute(new Runnable() {
2.39 + @Override
2.40 + public void run() {
2.41 + int id = ActiveSessions.getInstance().createSession(serverCtx, env);
2.42 + final AttachResult attachResult = new AttachResult();
2.43 + attachResult.setId(id);
2.44 + attachResult.setType(type);
2.45 + attachResult.setState(state);
2.46 + attachResult.setStatus(id < 0 ?
2.47 + Status.not_found :
2.48 + Status.done);
2.49 + env.sendObject(attachResult);
2.50 + }
2.51 + });
2.52 }
2.53 - if (id >= 0) {
2.54 - status = Status.done;
2.55 - }
2.56 - final AttachResult attachResult = new AttachResult();
2.57 - attachResult.setId(id);
2.58 - attachResult.setType(type);
2.59 - attachResult.setState(state);
2.60 - attachResult.setStatus(status);
2.61 - env.sendObject(attachResult);
2.62 - return Status.accepted;
2.63 + return status;
2.64 }
2.65 }