Esempio n. 1
0
File: mqi.c Progetto: 01org/murphy
int mqi_rollback_transaction(mqi_handle_t h)
{
    uint32_t           depth = TX_DEPTH(h);
    uint32_t           useid = TX_USEID(h);
    mqi_transaction_t *tx;
    mqi_db_t          *db;
    mqi_db_functbl_t  *ftb;
    int                err;
    int                i;

    MDB_CHECKARG(h != MQI_HANDLE_INVALID && depth < MQI_TXDEPTH_MAX, -1);
    MDB_PREREQUISITE(dbs && ndb > 0, -1);
    MDB_ASSERT(txdepth > 0 && depth == (uint32_t)txdepth - 1, EBADSLT, -1);

    tx = txstack + depth;

    MDB_ASSERT(tx->useid == useid, EBADSLT, -1);

    for (i = 0, err = 0;  i < ndb;  i++) {
        db  = dbs + i;
        ftb = db->functbl;

        if (ftb->rollback_transaction(tx->txid[i]) < 0)
            err = -1;
    }

    txdepth--;

    return err;
}
Esempio n. 2
0
// creating/waiting status edu can be deactivated (pooled)
// deactivateEDU supposed only happened to AGENT EDUs
// any EDUs other than AGENT will be destroyed and MDB_SYS will be returned
int pmdEDUMgr::_deactivateEDU ( EDUID eduID )
{
   int rc         = MDB_OK ;
   unsigned int eduStatus = PMD_EDU_CREATING ;
   pmdEDUCB* eduCB  = NULL ;
   std::map<EDUID, pmdEDUCB*>::iterator it ;
   // cross queue operation, need X lock
   _mutex.get() ;
   if ( _runQueue.end () == ( it = _runQueue.find ( eduID )) )
   {
      // if it's not in run queue, then is it in idle queue?
      // if it's already idle, we don't need to do anything
      if ( _idleQueue.end() != _idleQueue.find ( eduID )  )
      {
         goto done ;
      }
      // we can't find EDU in run queue
      rc = MDB_SYS ;
      goto error ;
   }
   eduCB = ( *it ).second ;

   eduStatus = eduCB->getStatus () ;

   // if it's already idle, let's get out of here
   if ( PMD_IS_EDU_IDLE ( eduStatus ) )
      goto done ;

   if ( !PMD_IS_EDU_WAITING ( eduStatus ) &&
        !PMD_IS_EDU_CREATING ( eduStatus ) )
   {
      rc = MDB_EDU_INVAL_STATUS ;
      goto error ;
   }

   // only Agent can be deactivated (pooled), other system
   // EDUs can only be destroyed
   MDB_ASSERT ( isPoolable ( eduCB->getType() ),
                "Only agent can be pooled" )
   _runQueue.erase ( eduID ) ;
   eduCB->setStatus ( PMD_EDU_IDLE ) ;
   _idleQueue [ eduID ] = eduCB ;
done :
   _mutex.release () ;
   return rc ;
error :
   goto done ;
}
Esempio n. 3
0
File: mqi.c Progetto: 01org/murphy
mqi_handle_t mqi_begin_transaction(void)
{
    mqi_transaction_t *tx;
    mqi_db_t          *db;
    mqi_db_functbl_t  *ftb;
    uint32_t           depth;
    int                i;

    MDB_PREREQUISITE(dbs && ndb > 0 && transact_handle, MQI_HANDLE_INVALID);
    MDB_ASSERT(txdepth < MQI_TXDEPTH_MAX - 1, EOVERFLOW, MQI_HANDLE_INVALID);

    depth = txdepth++;
    tx = txstack + depth;

    TX_USEID_INCREMENT(tx->useid);

    for (i = 0; i < ndb; i++) {
        db  = dbs + i;
        ftb = db->functbl;
        tx->txid[i] = ftb->begin_transaction();
    }

    return TX_HANDLE(tx->useid, depth);
}
Esempio n. 4
0
File: mqi.c Progetto: 01org/murphy
mqi_handle_t mqi_create_table(char *name,
                              uint32_t flags,
                              char **index_columns,
                              mqi_column_def_t *cdefs)
{
    mqi_db_t         *db;
    mqi_db_functbl_t *ftb;
    mqi_table_t      *tbl = NULL;
    mqi_handle_t      h = MQI_HANDLE_INVALID;
    char             *namedup = NULL;
    int               i;

    MDB_CHECKARG(name && cdefs, MQI_HANDLE_INVALID);
    MDB_PREREQUISITE(dbs && ndb > 0, MQI_HANDLE_INVALID);

    for (i = 0, ftb = NULL;  i < ndb;  i++) {
        db = dbs + i;

        if ((DB_TYPE(db) & flags) != 0) {
            ftb = db->functbl;
            break;
        }
    }

    MDB_ASSERT(ftb, ENOENT, MQI_HANDLE_INVALID);

    if(!(tbl = calloc(1, sizeof(mqi_table_t))))
        return MQI_HANDLE_INVALID;

    tbl->db = db;
    tbl->handle = NULL;

    if (!(namedup = strdup(name)))
        goto cleanup;

    if (!(tbl->handle = ftb->create_table(name, index_columns, cdefs)))
        goto cleanup;

    if ((h = mdb_handle_add(table_handle, tbl)) == MQI_HANDLE_INVALID)
        goto cleanup;

    if (mdb_hash_add(table_name_hash, 0,namedup, NULL + h) < 0) {
        mdb_handle_delete(table_handle, h);
        h = MQI_HANDLE_INVALID;
    }

    ftb->register_table_handle(tbl->handle, h);

    return h;

 cleanup:
    if (tbl) {
        if (tbl->handle) {
            mdb_handle_delete(table_handle, h);
            ftb->drop_table(tbl->handle);
        }
        mdb_hash_delete(table_name_hash, 0,name);
        free(namedup);
        free(tbl);
    }

    return MDB_HANDLE_INVALID;
}
Esempio n. 5
0
// get an EDU from idle pool, if idle pool is empty, create new one
int pmdEDUMgr::startEDU ( EDU_TYPES type, void* arg, EDUID *eduid )
{
   int     rc = MDB_OK ;
   EDUID     eduID = 0 ;
   pmdEDUCB* eduCB = NULL ;
   std::map<EDUID, pmdEDUCB*>::iterator it ;

   if ( isQuiesced () )
   {
      rc = MDB_QUIESCED ;
      goto done ;
   }
   /****************** CRITICAL SECTION **********************/
   // get exclusive latch, we don't latch the entire function
   // in order to avoid creating new thread while holding latch
   _mutex.get () ;
   // if there's any pooled EDU?
   // or is the request type can be pooled ?
   if ( true == _idleQueue.empty () || !isPoolable ( type ) )
   {
      // note that EDU types other than "agent" shouldn't be pooled at all
      // release latch before calling createNewEDU
      _mutex.release () ;
      rc = _createNewEDU ( type, arg, eduid ) ;
      if ( MDB_OK == rc )
         goto done ;
      goto error ;
   }

   // if we can find something in idle queue, let's get the first of it
   for ( it = _idleQueue.begin () ;
         ( _idleQueue.end () != it ) &&
         ( PMD_EDU_IDLE != ( *it ).second->getStatus ()) ;
         it ++ ) ;

   // if everything in idleQueue are in DESTROY status, we still need to
   // create a new EDU
   if ( _idleQueue.end () == it )
   {
      // release latch before calling createNewEDU
      _mutex.release () ;
      rc = _createNewEDU ( type, arg, eduid  ) ;
      if ( MDB_OK == rc )
         goto done ;
      goto error ;
   }

   // now "it" is pointing to an idle EDU
   // note that all EDUs in the idleQueue should be AGENT type
   eduID = ( *it ).first ;
   eduCB = ( *it ).second ;
   _idleQueue.erase ( eduID ) ;
   MDB_ASSERT ( isPoolable ( type ),
                "must be agent" )
   // switch agent type for the EDU ( call different agent entry point )
   eduCB->setType ( type ) ;
   eduCB->setStatus ( PMD_EDU_WAITING ) ;
   _runQueue [ eduID ] = eduCB ;
   *eduid = eduID ;
   _mutex.release () ;
   /*************** END CRITICAL SECTION **********************/

   //The edu is start, need post a resum event
   eduCB->postEvent( pmdEDUEvent( PMD_EDU_EVENT_RESUME, false, arg ) ) ;

done :
   return rc ;
error :
   goto done ;
}