Exposed the mechanism for locking down client objects during a client
session so that fake sessions can effect their own locking. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1294 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
//
|
//
|
||||||
// $Id: ClientManager.java,v 1.17 2002/04/18 22:37:08 mdb Exp $
|
// $Id: ClientManager.java,v 1.18 2002/04/26 02:32:27 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.server;
|
package com.threerings.presents.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import com.threerings.presents.Log;
|
import com.threerings.presents.Log;
|
||||||
@@ -171,12 +172,49 @@ public class ClientManager implements ConnectionObserver
|
|||||||
{
|
{
|
||||||
// we only remove the mapping if there's not a session in progress
|
// we only remove the mapping if there's not a session in progress
|
||||||
// (which is indicated by a mapping in the usermap table)
|
// (which is indicated by a mapping in the usermap table)
|
||||||
if (!_usermap.containsKey(username)) {
|
if (!_locks.contains(username)) {
|
||||||
ClientObject clobj = (ClientObject)_objmap.remove(username);
|
ClientObject clobj = (ClientObject)_objmap.remove(username);
|
||||||
PresentsServer.omgr.destroyObject(clobj.getOid());
|
PresentsServer.omgr.destroyObject(clobj.getOid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a client object becomes part of an active session, this method
|
||||||
|
* should be called to ensure that it is not unloaded by any entities
|
||||||
|
* that temporarily resolve and release the object. This is called
|
||||||
|
* automatically when a real user starts a session by establishing a
|
||||||
|
* network connection with the server. If a client session is managed
|
||||||
|
* via some other mechanism (bots managed by the server, for example),
|
||||||
|
* this method and its corresponding {@link #releaseClientObject}
|
||||||
|
* should be called at the beginning and end of the faked client
|
||||||
|
* session respectively.
|
||||||
|
*/
|
||||||
|
public synchronized void lockClientObject (String username)
|
||||||
|
{
|
||||||
|
if (_locks.contains(username)) {
|
||||||
|
Log.warning("Requested to lock already locked user " +
|
||||||
|
"[username=" + username + "].");
|
||||||
|
Thread.dumpStack();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_locks.add(username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases a client object when their session has ended.
|
||||||
|
*
|
||||||
|
* @see #lockClientObject
|
||||||
|
*/
|
||||||
|
public synchronized void releaseClientObject (String username)
|
||||||
|
{
|
||||||
|
if (!_locks.remove(username)) {
|
||||||
|
Log.warning("Requested to unlock a user that was not locked " +
|
||||||
|
"[username=" + username + "].");
|
||||||
|
Thread.dumpStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
public synchronized void connectionEstablished (
|
public synchronized void connectionEstablished (
|
||||||
Connection conn, AuthRequest req, AuthResponse rsp)
|
Connection conn, AuthRequest req, AuthResponse rsp)
|
||||||
@@ -197,8 +235,14 @@ public class ClientManager implements ConnectionObserver
|
|||||||
", conn=" + conn + "].");
|
", conn=" + conn + "].");
|
||||||
// create a new client and stick'em in the table
|
// create a new client and stick'em in the table
|
||||||
try {
|
try {
|
||||||
|
// create a client and start up its session
|
||||||
client = (PresentsClient)_clientClass.newInstance();
|
client = (PresentsClient)_clientClass.newInstance();
|
||||||
client.startSession(this, username, conn);
|
client.startSession(this, username, conn);
|
||||||
|
|
||||||
|
// lock this client for the duration of this session
|
||||||
|
lockClientObject(username);
|
||||||
|
|
||||||
|
// map their client instance
|
||||||
_usermap.put(username, client);
|
_usermap.put(username, client);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -258,8 +302,10 @@ public class ClientManager implements ConnectionObserver
|
|||||||
String username = client.getUsername();
|
String username = client.getUsername();
|
||||||
// remove the client from the username map
|
// remove the client from the username map
|
||||||
PresentsClient rc = (PresentsClient)_usermap.remove(username);
|
PresentsClient rc = (PresentsClient)_usermap.remove(username);
|
||||||
// and the client object mapping as well
|
// release the client session
|
||||||
_objmap.remove(username);
|
releaseClientObject(username);
|
||||||
|
// and unmap (and destroy) their client object
|
||||||
|
unmapClientObject(username);
|
||||||
|
|
||||||
// sanity check just because we can
|
// sanity check just because we can
|
||||||
if (rc == null) {
|
if (rc == null) {
|
||||||
@@ -285,6 +331,9 @@ public class ClientManager implements ConnectionObserver
|
|||||||
/** A mapping of pending client resolvers. */
|
/** A mapping of pending client resolvers. */
|
||||||
protected HashMap _penders = new HashMap();
|
protected HashMap _penders = new HashMap();
|
||||||
|
|
||||||
|
/** A set containing the usernames of all locked clients. */
|
||||||
|
protected HashSet _locks = new HashSet();
|
||||||
|
|
||||||
/** The client class in use. */
|
/** The client class in use. */
|
||||||
protected Class _clientClass = PresentsClient.class;
|
protected Class _clientClass = PresentsClient.class;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: PresentsClient.java,v 1.29 2002/03/05 06:15:43 mdb Exp $
|
// $Id: PresentsClient.java,v 1.30 2002/04/26 02:32:27 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.server;
|
package com.threerings.presents.server;
|
||||||
|
|
||||||
@@ -278,11 +278,9 @@ public class PresentsClient
|
|||||||
// about to generate
|
// about to generate
|
||||||
clearSubscrips();
|
clearSubscrips();
|
||||||
|
|
||||||
// then let the client manager know what's up
|
// then let the client manager know what's up (it will take care
|
||||||
|
// of destroying our client object for us)
|
||||||
_cmgr.clientDidEndSession(this);
|
_cmgr.clientDidEndSession(this);
|
||||||
|
|
||||||
// destroy the client object
|
|
||||||
PresentsServer.omgr.destroyObject(_clobj.getOid());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user