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:
Michael Bayne
2002-04-26 02:32:27 +00:00
parent 57a937839d
commit e3fafb5b8c
2 changed files with 56 additions and 9 deletions
@@ -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());
} }
/** /**