In this instance, the EVENT_USER_LOST is triggered and we are checking to see if they room they left is empty, so we can delete it. We have already discovered (and reported and received an interim patch) the NegativeArraySizeException when calling Room.getAllUsersButOne (http://forums.smartfoxserver.com/viewto ... highlight=). We have seen that the user is asynchronously removed from the server/room they were in at sometime during the extension handling, but the exact timing is different everytime. Sometimes by the time we check the room the user was in, its size is 0 and we just destroy it. Other times we check the room and there is 1 user in the room, which is the current user who is going to leave - this is why we use the getAllUsersButOne so we can see if there is anyone else left in the room.
Because of this asynchronous remove, we have programmed this section of code quite defensively as the following code demonstrates:
Code: Select all
synchronized(ownerRooms)
{
int userCount = room.howManyUsers();
if (userCount == 0)
{
//Empty room, delete it
cleanupRoom(ownerRooms, room, roomSubTypeId, ownerId);
return false;
}
if ( user != null )
{
User usersRemaining[] = room.getAllUsersButOne(user.getUserId());
if ( usersRemaining == null || ( userCount == 1 && usersRemaining.length == 0) )
{
// See if the user is still in the room
// could have been removed since we last checked
if (room.howManyUsers() == 1)
{
room.removeUser(user,true,true);
}
cleanupRoom(ownerRooms, room, roomSubTypeId, ownerId);
return false;
}
}
}
But we occasionaly get the following error:
[ WARNING ] [id: 45] (Room.removeUser): Couldn't remove user: mmo_user1832:2760, from room: Private-7--9223372036854762552
What I think must be happening is that in the sfs Room.removeUser it checks if the user exists, locks the room, and then tries to remove the user, but they have already been asynchronously removed between the check and the lock event.
I think it should be, check if they exist, lock, check if they exist and then remove.