/** * Attach an activity to an interpreter instance * * @param instance The interpreter instance involved. * * @return Either an existing activity, or a new activity created for * this thread. */ Activity *ActivityManager::attachThread() { // it's possible we already have an activity active for this thread. That // most likely occurs in nested RexxStart() calls. Activity *oldActivity = findActivity(); // we have an activity created for this thread already. The interpreter instance // should already have handled the case of an attach for an already attached thread. // so we're going to have a new activity to create, and potentially an existing one to // suspend // we need to lock the kernel to have access to the memory manager to // create this activity. lockKernel(); Activity *activityObject = createCurrentActivity(); // Do we have a nested interpreter call occurring on the same thread? We need to // mark the old activity as suspended, and chain this to the new activity. if (oldActivity != OREF_NULL) { oldActivity->setSuspended(true); // this pushes this down the stack. activityObject->setNestedActivity(oldActivity); } unlockKernel(); /* release kernel semaphore */ // now we need to have this activity become the kernel owner. activityObject->requestAccess(); // this will help ensure that the code after the request access call // is only executed after access acquired. sentinel = true; // belt-and-braces. Make sure the current activity is explicitly set to // this activity before leaving. currentActivity = activityObject; return activityObject; }
/** * Return an activity to the activity pool. * * @param activityObject * The released activity. */ void ActivityManager::returnActivity(Activity *activityObject) { // START OF CRITICAL SECTION { ResourceSection lock; // remove this from the activte list allActivities->removeItem(activityObject); // if we ended up pushing an old activity down when we attached this // thread, then we need to restore the old thread to active state. Activity *oldActivity = activityObject->getNestedActivity(); if (oldActivity != OREF_NULL) { oldActivity->setSuspended(false); } // cleanup any system resources this activity might own activityObject->cleanupActivityResources(); } }
/** * Get a root activity for a new interpreter instance. * * @return The newly created activity. */ Activity *ActivityManager::getRootActivity() { // it's possible we already have an activity active for this thread. That // most likely occurs in nested RexxStart() calls. Get that activity first, // and if we have one, we'll need to push this down. Activity *oldActivity = findActivity(); // we need to lock the kernel to have access to the memory manager to // create this activity. lockKernel(); // get a new activity object Activity *activityObject = createCurrentActivity(); unlockKernel(); // mark this as the root activity for an interpreter instance. Some operations // are only permitted from the root threads. activityObject->setInterpreterRoot(); // Do we have a nested interpreter call occurring on the same thread? We need to // mark the old activity as suspended, and chain this to the new activity. if (oldActivity != OREF_NULL) { oldActivity->setSuspended(true); // this pushes this down the stack. activityObject->setNestedActivity(oldActivity); } // now we need to have this activity become the kernel owner. activityObject->requestAccess(); // this will help ensure that the code after the request access call // is only executed after access acquired. sentinel = true; activityObject->activate(); // let the activity know it's in use, potentially nested // belt-and-braces. Make sure the current activity is explicitly set to // this activity before leaving. currentActivity = activityObject; return activityObject; }