Exemple #1
0
void
ThreadCreate(TThread **      const threadPP,
             void *          const userHandle,
             TThreadProc   * const func,
             TThreadDoneFn * const threadDone,
             bool            const useSigchld,
             size_t          const stackSize,
             const char **   const errorP) {
    
    TThread * threadP;

    MALLOCVAR(threadP);
    if (threadP == NULL)
        xmlrpc_asprintf(errorP,
                        "Can't allocate memory for thread descriptor.");
    else {
        sigset_t oldBlockedSet;
        pid_t rc;

        threadP->nextInPoolP = NULL;
        threadP->threadDone  = threadDone;
        threadP->userHandle  = userHandle;
        threadP->useSigchld  = useSigchld;
        threadP->pid         = 0;

        /* We have to be sure we don't get the SIGCHLD for this child's
           death until the child is properly registered in the thread pool
           so that the handler will know who he is.
        */
        blockSignalClass(SIGCHLD, &oldBlockedSet);

        rc = fork();
        
        if (rc < 0)
            xmlrpc_asprintf(errorP, "fork() failed, errno=%d (%s)",
                            errno, strerror(errno));
        else if (rc == 0) {
            /* This is the child */
            (*func)(userHandle);
            /* Note that thread cleanup (threadDone) is done by the _parent_,
               upon seeing our exit.
            */
            exit(0);
        } else {
            /* This is the parent */
            threadP->pid = rc;

            addToPool(threadP);

            sigprocmask(SIG_SETMASK, &oldBlockedSet, NULL);  /* restore */

            *errorP = NULL;
            *threadPP = threadP;
        }
        if (*errorP) {
            removeFromPool(threadP);
            free(threadP);
        }
    }
}
Exemple #2
0
void OperationList::registerObject(BaseObject *object, unsigned op_type, int object_idx,  BaseObject *parent_obj)
{
	ObjectType obj_type;
	Operation *operation=NULL;
	Table *parent_tab=NULL;
	Relationship *parent_rel=NULL;
	int obj_idx=-1;

	try
	{
		//Raises an error if the user tries to register an operation with null object
		if(!object)
			throw Exception(ERR_ASG_NOT_ALOC_OBJECT,__PRETTY_FUNCTION__,__FILE__,__LINE__);

		obj_type=object->getObjectType();
		if((obj_type==OBJ_COLUMN || obj_type==OBJ_CONSTRAINT ||
				obj_type==OBJ_INDEX || obj_type==OBJ_TRIGGER ||
				obj_type==OBJ_RULE) && !parent_obj)
			throw Exception(ERR_OPR_NOT_ALOC_OBJECT,__PRETTY_FUNCTION__,__FILE__,__LINE__);

		else if(parent_obj &&
						(((obj_type==OBJ_COLUMN || obj_type==OBJ_CONSTRAINT) &&
							(parent_obj->getObjectType()!=OBJ_RELATIONSHIP && parent_obj->getObjectType()!=OBJ_TABLE)) ||

						 ((obj_type==OBJ_INDEX || obj_type==OBJ_TRIGGER || obj_type==OBJ_RULE) &&
							parent_obj->getObjectType()!=OBJ_TABLE)))
			throw Exception(ERR_OPR_OBJ_INV_TYPE,__PRETTY_FUNCTION__,__FILE__,__LINE__);

		//If the operations list is full makes the automatic cleaning before inserting a new operation
		if(current_index == static_cast<int>(max_size-1))
			removeOperations();

		/* If adding an operation and the current index is not pointing
		 to the end of the list (available redo / user ran undo operations)
		 all elements from the current index to the end of the list will be deleted
		 as well as the objects in the pool that were linked to the excluded operations */
		if(current_index>=0 && static_cast<unsigned>(current_index)!=operations.size())
		{
			//Gets the last operation index
			int i=operations.size()-1;

			//Removes all the operation while the current index isn't reached
			while(i >= current_index)
			{
				removeFromPool(i);
				i--;
			}

			//Validates the remaining operatoins after the deletion
			validateOperations();
		}

		//Creates the new operation
		operation=new Operation;
		operation->op_type=op_type;
		operation->chain_type=next_op_chain;
		operation->original_obj=object;

		//Adds the object on te pool
		addToPool(object, op_type);

		//Assigns the pool object to the operation
		operation->pool_obj=object_pool.back();

		if(next_op_chain==Operation::CHAIN_START)
			next_op_chain=Operation::CHAIN_MIDDLE;

		/*  Performing specific operations according to the type of object.
		 If the object has a parent object, it must be discovered
		 and moreover it is necessary to find and store the index of the object
		 in the list on the parent object */
		if(obj_type==OBJ_COLUMN || obj_type==OBJ_CONSTRAINT ||
			 obj_type==OBJ_INDEX || obj_type==OBJ_TRIGGER ||
			 obj_type==OBJ_RULE)
		{
			TableObject *tab_obj=NULL;
			tab_obj=dynamic_cast<TableObject *>(object);

			if(parent_obj->getObjectType()==OBJ_TABLE)
				parent_tab=dynamic_cast<Table *>(parent_obj);
			else
				parent_rel=dynamic_cast<Relationship *>(parent_obj);

			/* Specific case to columns: on removal operations the permissions of the objects
			must be removed too */
			if(obj_type==OBJ_COLUMN && op_type==Operation::OBJECT_REMOVED)
				model->removePermissions(tab_obj);
			else if(((obj_type==OBJ_TRIGGER && dynamic_cast<Trigger *>(tab_obj)->isReferRelationshipAddedColumn()) ||
							 (obj_type==OBJ_INDEX && dynamic_cast<Index *>(tab_obj)->isReferRelationshipAddedColumn()) ||
							 (obj_type==OBJ_CONSTRAINT && dynamic_cast<Constraint *>(tab_obj)->isReferRelationshipAddedColumn())))
			{
				if(op_type==Operation::OBJECT_REMOVED)
					tab_obj->setParentTable(parent_tab);

				operation->xml_definition=model->validateObjectDefinition(tab_obj, SchemaParser::XML_DEFINITION);
			}

			operation->parent_obj=parent_obj;

			/* If there is a parent relationship will get the index of the object.
			Only columns and constraints are handled case the parent is a relationship */
			if(parent_rel && (obj_type==OBJ_COLUMN || obj_type==OBJ_CONSTRAINT))
			{
				//Case a specific index wasn't specified
				if(object_idx < 0)
					//Stores on the operation the index on its parent
					obj_idx=parent_rel->getObjectIndex(tab_obj);
				else
					//Assigns the specific index to operation
					obj_idx=object_idx;
			}
			//Case there is a parent table will get the object's index
			else if(parent_tab)
			{
				if(object_idx < 0)
					//Stores on the operation the index of object on its parent
					obj_idx=parent_tab->getObjectIndex(object->getName(false), obj_type);
				else
					obj_idx=object_idx;
			}
			//Raises an error if both parent table / relationship isn't allocated
			else
				throw Exception(ERR_OPR_NOT_ALOC_OBJECT,__PRETTY_FUNCTION__,__FILE__,__LINE__);
		}
		else
		{
			//Case a specific index wasn't specified
			if(object_idx < 0)
				//Stores on the operation the object index on the model
				obj_idx=model->getObjectIndex(object);
			else
				//Assigns the specific index to object
				obj_idx=object_idx;
		}

		operation->object_idx=obj_idx;
		operations.push_back(operation);
		current_index=operations.size();
	}
	catch(Exception &e)
	{
		if(operation)
		{
			removeFromPool(object_pool.size()-1);
			delete(operation);
		}
		throw Exception(e.getErrorMessage(),e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e);
	}
}
void StackElement::Release()
{
    if (pool && !IsShared())
        addToPool();
    CInterface::Release();
}