JSBool JavaObject::setProperty(JSContext* ctx, JSObject* obj, jsid id, JSBool strict, jsval* vp) { #endif //GECKO_VERSION Debug::log(Debug::Spam) << "JavaObject::setProperty obj=" << obj << Debug::flush; if (!JSID_IS_INT(id)) { Debug::log(Debug::Error) << " Error: setting string property id" << Debug::flush; // TODO: throw a better exception here return JS_FALSE; } SessionData* data = JavaObject::getSessionData(ctx, obj); if (!data) { return JS_TRUE; } int objectRef = JavaObject::getObjectId(ctx, obj); int dispId = JSID_TO_INT(id); Value value; data->makeValueFromJsval(value, ctx, *vp); HostChannel* channel = data->getHostChannel(); SessionHandler* handler = data->getSessionHandler(); if (!ServerMethods::setProperty(*channel, handler, objectRef, dispId, value)) { // TODO: throw a better exception here return JS_FALSE; } return JS_TRUE; }
void JavaObject::finalize(JSContext* ctx, JSObject* obj) { Debug::log(Debug::Spam) << "JavaObject::finalize obj=" << obj << " objId=" << JavaObject::getObjectId(ctx, obj) << Debug::flush; SessionData* data = JavaObject::getSessionData(ctx, obj); if (data) { int objectId = JavaObject::getObjectId(ctx, obj); data->freeJavaObject(objectId); JS_SetPrivate(ctx, obj, NULL); } }
void JavaObject::finalize(JSFreeOp* fop, JSObject* obj) { // In general use of JS_GetPrivate is not safe but it is OK in the finalizer // according to: // https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_GetPrivate // We will not be using getSession for that reason. SessionData * data = static_cast<SessionData*>(JS_GetPrivate(obj)); if (data) { jsval val = JS_GetReservedSlot(obj, 0); int objectId = JSVAL_TO_INT(val); data->freeJavaObject(objectId); MOZ_JS_SetPrivate(/** Post-FF13 requires no ctx anyways*/ NULL, obj, NULL); } }
// release all the sessions associated with this token bool SessionManager::releaseSessions( uint32 token ) { m_mtx.lock(); // do we have the session? SessionUserMap::iterator pos = m_susers.find( token ); if( pos != m_susers.end() ) { // copy the list of sessions to be closed, so that we can work on it. SessionList lCopy = pos->second; m_susers.erase( pos ); m_mtx.unlock(); SessionList::iterator iter = lCopy.begin(); while( iter != lCopy.end() ) { SessionData::WeakRef* wsd = *iter; SessionData* sd = wsd->get(); // Still a valid reference? if( sd != 0 ) { // store on persistent media sd->store(); // mark as used now sd->touch(); // make available for other requests m_mtx.lock(); if( timeout() > 0 ) { m_expmap.insert( ExpirationMap::value_type( sd->lastTouched() + timeout(), sd->getWeakRef() ) ); } sd->release(); m_mtx.unlock(); } wsd->dropped(); ++iter; } } else { m_mtx.unlock(); } return true; }
JSBool JavaObject::getProperty(JSContext* ctx, JSObject* obj, jsid id, jsval* rval) { Debug::log(Debug::Spam) << "JavaObject::getProperty obj=" << obj << Debug::flush; SessionData* data = JavaObject::getSessionData(ctx, obj); if (!data) { // TODO: replace the frame with an error page instead? *rval = JSVAL_VOID; return JS_TRUE; } int objectRef = JavaObject::getObjectId(ctx, obj); if (JSID_IS_STRING(id)) { JSString* str = JSID_TO_STRING(id); if ((JS_GetStringEncodingLength(ctx, str) == 8) && !strncmp("toString", JS_EncodeString(ctx, str), 8)) { *rval = data->getToStringTearOff(); return JS_TRUE; } if ((JS_GetStringEncodingLength(ctx, str) == 2) && !strncmp("id", JS_EncodeString(ctx, str), 2)) { *rval = INT_TO_JSVAL(objectRef); return JS_TRUE; } if ((JS_GetStringEncodingLength(ctx, str) == 16) && !strncmp("__noSuchMethod__", JS_EncodeString(ctx, str), 16)) { // Avoid error spew if we are disconnected *rval = JSVAL_VOID; return JS_TRUE; } // TODO: dumpJsVal can no longer handle this case //Debug::log(Debug::Error) << "Getting unexpected string property " // << dumpJsVal(ctx, id) << Debug::flush; // TODO: throw a better exception here return JS_FALSE; } if (!JSID_IS_INT(id)) { // TODO: dumpJsVal can no longer handle this case //Debug::log(Debug::Error) << "Getting non-int/non-string property " // << dumpJsVal(ctx, id) << Debug::flush; // TODO: throw a better exception here return JS_FALSE; } int dispId = JSID_TO_INT(id); HostChannel* channel = data->getHostChannel(); SessionHandler* handler = data->getSessionHandler(); gwt::Value value = ServerMethods::getProperty(*channel, handler, objectRef, dispId); data->makeJsvalFromValue(*rval, ctx, value); return JS_TRUE; }
SessionData* SessionManager::startSession( uint32 token ) { SessionData* sd = 0; Falcon::String sSID; // No one can possibly use this SD as no one can know it. sd = createUniqueId( sSID ); m_mtx.lock(); m_susers[token].push_back( sd->getWeakRef() ); // assign the session sd->assign( token ); m_mtx.unlock(); return sd; }
/** * Called when the JavaObject is invoked as a function. * We ignore the JSObject* argument, which is the 'this' context, which is * usually the window object. The JavaObject instance is in argv[-2]. * * Returns a JS array, with the first element being a boolean indicating that * an exception occured, and the second element is either the return value or * the exception which was thrown. In this case, we always return false and * raise the exception ourselves. */ JSBool JavaObject::call(JSContext* ctx, JSObject*, uintN argc, jsval* argv, jsval* rval) { // Get the JavaObject called as a function JSObject* obj = JSVAL_TO_OBJECT(argv[-2]); if (argc < 2 || !JSVAL_IS_INT(argv[0]) || #ifdef JSVAL_IS_OBJECT !JSVAL_IS_OBJECT(argv[1])) { #else (JSVAL_IS_PRIMITIVE(argv[1]) && !JSVAL_IS_NULL(argv[1]))) { #endif Debug::log(Debug::Error) << "JavaObject::call incorrect arguments" << Debug::flush; return JS_FALSE; } int dispId = JSVAL_TO_INT(argv[0]); if (Debug::level(Debug::Spam)) { Debug::DebugStream& dbg = Debug::log(Debug::Spam) << "JavaObject::call oid=" << JavaObject::getObjectId(ctx, obj) << ",dispId=" << dispId << " ("; for (unsigned i = 2; i < argc; ++i) { if (i > 2) { dbg << ", "; } dbg << dumpJsVal(ctx, argv[i]); } dbg << ")" << Debug::flush; } SessionData* data = JavaObject::getSessionData(ctx, obj); if (!data) { *rval = JSVAL_VOID; return JS_TRUE; } Debug::log(Debug::Spam) << "Data = " << data << Debug::flush; gwt::Value javaThis; if (!JSVAL_IS_NULL(argv[1])) { JSObject* thisObj = JSVAL_TO_OBJECT(argv[1]); if (isJavaObject(ctx, thisObj)) { javaThis.setJavaObject(getObjectId(ctx, thisObj)); } else { data->makeValueFromJsval(javaThis, ctx, argv[1]); } } else { int oid = getObjectId(ctx, obj); javaThis.setJavaObject(oid); } return invokeJava(ctx, data, javaThis, dispId, argc - 2, &argv[2], rval); }
SessionData* SessionManager::startSession( uint32 token, const Falcon::String &sSID ) { SessionData* sd = 0; m_mtx.lock(); if ( m_smap.find( sSID ) == m_smap.end() ) { sd = createSession(sSID); m_smap[ sSID ] = sd; m_susers[token].push_back( sd->getWeakRef() ); // assign the session sd->assign( token ); } m_mtx.unlock(); // else, it's still 0 return sd; }
void AuthSession::process(const SessionData &sessionData, const QString &mechanism) { m_mechanism = mechanism; m_sessionData = sessionData.toMap(); m_sessionData.insert("credentialsId", m_id); responseTimer.start(); }
bool SessionManager::closeSession( const String& sSID, uint32 token ) { m_mtx.lock(); SessionMap::iterator iter = m_smap.find( sSID ); if( iter != m_smap.end() ) { SessionData* sd = iter->second; m_smap.erase( sSID ); sd->clearRefs(); m_mtx.unlock(); sd->dispose(); delete sd; return true; } m_mtx.unlock(); return false; }
void SessionManager::expireOldSessions() { numeric now = Sys::_seconds(); std::deque<SessionData*> expiredSessions; m_mtx.lock(); while( ! m_expmap.empty() && m_expmap.begin()->first < now ) { SessionData::WeakRef* wsd = m_expmap.begin()->second; SessionData* sd = wsd->get(); // Is the session still alive? if ( sd != 0 && sd->lastTouched() + timeout() < now ) { // the data is dead, so we remove it now from the available map m_smap.erase( sd->sID() ); // prevents others (and ourselves) to use it again sd->clearRefs(); // and we push it aside for later clearing expiredSessions.push_back( sd ); } // also, take it away from our expired data m_expmap.erase( m_expmap.begin() ); } m_mtx.unlock(); // now we can destroy the expired sessions std::deque<SessionData*>::iterator elem = expiredSessions.begin(); while( elem != expiredSessions.end() ) { SessionData* sd = *elem; sd->dispose(); delete sd; ++elem; } }
SessionData* SessionManager::getSession( const Falcon::String& sSID, uint32 token ) { SessionData* sd = 0; bool bCreated; // Should we start a new thread for this? if( timeout() > 0 ) expireOldSessions(); m_mtx.lock(); SessionMap::iterator iter = m_smap.find( sSID ); if( iter != m_smap.end() ) { sd = iter->second; if ( sd == 0 || sd->isAssigned() ) { m_mtx.unlock(); return 0; } sd->assign( token ); // We must manipulate m_susers in the lock to prevent concurrent update // from other threads. m_susers[token].push_back( sd->getWeakRef() ); // now that the session is assigned, we are free to manipulate it outside the lock. m_mtx.unlock(); bCreated = false; } else { // create the session (fast) sd = createSession( sSID ); // assign to our maps m_smap[sSID] = sd; m_susers[token].push_back( sd->getWeakRef() ); // assign the session sd->assign( token ); // try to resume after unlock m_mtx.unlock(); bCreated = true; } // can we resume this session? if( ! sd->resume() ) { // all useless work. m_mtx.lock(); m_smap.erase( sSID ); sd->clearRefs(); m_mtx.unlock(); //If the session was created, we should have done it. if( ! bCreated ) { sd->setInvalid(); } else { delete sd; sd = 0; } } return sd; }