Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

qarm/qarmtransaction.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 MyARM GbR, Germany
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or 
00006  * without modification, are permitted provided that the 
00007  * following conditions are met:
00008  * 1. Redistributions of source code must retain the above
00009  *    copyright notice, this list of conditions and the
00010  *    following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above
00012  *    copyright notice, this list of conditions and the
00013  *    following disclaimer in the documentation and/or other
00014  *    materials provided with the distribution.
00015  * 3. All advertising materials mentioning features or use of
00016  *    this software must display the following acknowledgement:
00017  *        This product includes software developed by
00018  *        MyARM GbR and its contributors.
00019  * 4. Neither the name of MyARM GbR nor the names of its
00020  *    contributors may be used to endorse or promote products
00021  *    derived from this software without specific prior written
00022  *    permission.
00023  * 
00024  * THIS SOFTWARE IS PROVIDED BY MYARM GBR. AND CONTRIBUTORS 
00025  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
00026  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00027  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00028  * SHALL MYARM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00029  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00032  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00033  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00034  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00035  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00036  * OF SUCH DAMAGE.
00037  */
00038 
00039 
00045 #include <QArmTransaction>
00046 #include <QArmApplication>
00047 #include <QArmMetric>
00048 #include <QArmMetricList>
00049 #include <QArmTranDefinition>
00050 
00051 #include "arm4.h"
00052 
00053 /* hack to support correlator_getenv() functions which uses 
00054  * "static" arm calls. */
00055 static
00056 arm_error_t my_get_corrlen(const arm_correlator_t *correlator, 
00057                            arm_correlator_length_t *length);
00058 
00059 
00060 ARM4_API_DYNAMIC(arm_error_t)
00061 arm_get_correlator_length(const arm_correlator_t *correlator, 
00062                           arm_correlator_length_t *length)
00063 {
00064   return my_get_corrlen(correlator, length);
00065 }
00066 
00067 #include "myarmsdk.h"
00068 #include "myarmsdk_dynload.h"
00069 
00070 static
00071 arm_error_t my_get_corrlen(const arm_correlator_t *correlator, 
00072                            arm_correlator_length_t *length)
00073 {
00074   if((myarmsdkdyn_callbacks != NULL) && 
00075      (myarmsdkdyn_callbacks->get_correlator_length != NULL))            
00076     {  
00077       return myarmsdkdyn_callbacks->get_correlator_length(correlator, length);
00078     }
00079   return -1;
00080 }
00081 
00082 
00083 /*---------------------------------------------------------------------------*/
00084 
00085 QArmTransaction::QArmTransaction(const QArmTranDefinition & _trandef,
00086                                  QArmTransaction          * _parent) 
00087   :QArmInstance(_trandef), m_tranDefinition(0),
00088    m_children(0), m_tranParent(_parent) {
00089 
00090   connectParent();
00091 }
00092 
00093 /*---------------------------------------------------------------------------*/
00094 
00095 QArmTransaction::QArmTransaction(QArmTranDefinition * _trandef,
00096                                  QArmTransaction    * _parent) 
00097   :QArmInstance(*_trandef), m_tranDefinition(_trandef),
00098    m_children(0), m_tranParent(_parent) {
00099 
00100   connectParent();
00101 }
00102 
00103 /*---------------------------------------------------------------------------*/
00104 
00105 QArmTransaction::~QArmTransaction() {
00106 
00107   // If current transaction is active abort it!
00108   if(m_active)
00109     stop(QArmTransaction::ABORTED);
00110   // Subtract one from the child counter.
00111   if(m_tranParent != 0) {
00112     // Inform parent that there is a new child.
00113     m_tranParent->subtractChild();
00114   }
00115 }
00116 
00117 
00118 /*---------------------------------------------------------------------------*/
00119 
00120 void QArmTransaction::connectParent() {
00121   // Connect this object to the parent so that it will stop automatically
00122   // when the parent stops.
00123   if(m_tranParent != 0) {
00124     connect(m_tranParent,
00125             SIGNAL(stopped(const QArmStatus)),
00126             this,
00127             SLOT(stop(const QArmStatus)));
00128     // Inform parent that there is a new child.
00129     m_tranParent->addChild();
00130   }
00131 }
00132 
00133 /*---------------------------------------------------------------------------*/
00134 
00135 void QArmTransaction::start(const QArmApplication      * _app,
00136                             const QArmContextValueList * _context_values,
00137                             const QArmMetricList       * _metric_values) {
00138   
00139   if(!m_active) {
00140     armsdk_subbuffer_tran_context_t  sdk_sb_tran_context;
00141     armsdk_subbuffer_metric_values_t sdk_sb_metric_values;
00142     arm_subbuffer_user_t             sb_user;
00143     armsdk_buffer4_t                 buf4;
00144     int num_sb = 0;
00145 
00146     bool context = (_context_values != 0) && (_context_values->count() > 0);
00147     bool metrics = (_metric_values != 0) && (_metric_values->count() > 0);
00148 
00149     m_active = true;
00150       
00151     // CONTEXT VALUES
00152     // Undefined behaviour in case values and names/bindings do not match
00153     if(context) {
00154       // Initialize the context values buffer.
00155       armsdk_tran_context_initialize(&sdk_sb_tran_context);
00156       QArmContextValueListIterator it(*_context_values);
00157       int i = 0;
00158       while(it.hasNext()) {
00159         armsdk_tran_context_set(&sdk_sb_tran_context, 
00160                                 i, 
00161                                 it.next().toAscii().constData());
00162         ++i;
00163       }// end while
00164         
00165       num_sb = addSubbuffer(num_sb, buf4, ARM_SDKSB(sdk_sb_tran_context));
00166     }// end if
00167       
00168     // METRIC VALUES
00169     if(metrics) {
00170       // Initialize the metric values buffer.
00171       armsdk_metric_initialize(&sdk_sb_metric_values);
00172       // Fill it with content.
00173       QArmMetricListIterator it(*_metric_values);
00174       while(it.hasNext()) {
00175         it.next()->fill(&sdk_sb_metric_values);
00176       }// end while
00177         
00178       // Give this to the subbuffer.
00179       num_sb = addSubbuffer(num_sb, buf4, ARM_SDKSB(sdk_sb_metric_values));
00180     }// end if
00181       
00182 
00183     // USER handling
00184     if(!m_user.isEmpty()) {
00185       // Initialize the user buffer.
00186       armsdk_user_initialize(&sb_user);
00187         
00188       armsdk_user_set(&sb_user,
00189                       m_user.toAscii().constData());
00190         
00191       // and inform buf4.
00192       num_sb = addSubbuffer(num_sb, buf4, ARM_SB(sb_user));
00193     }
00194       
00195     // Check for a parent either from the outside 
00196     // (via environment variable) or from the inside
00197     if(m_tranParent != 0) {
00198       m_parentCorr = &m_tranParent->m_tranCorr;
00199     }
00200     else {
00201       m_parentCorr = myarmsdk_correlator_getenv(&m_parentCorrBuf,NULL); 
00202     }
00203     arm_start_transaction(_app->getHandle(),
00204                           m_id,
00205                           m_parentCorr,
00206                           ARM_FLAG_NONE,
00207                           num_sb > 0 ? &buf4.header : ARM_BUF4_NONE,
00208                           &m_tranHandle,
00209                           &m_tranCorr);
00210 
00211     // Now check for children. If there are any we do not need to set 
00212     // the environment variable. Otherwise we need to do it since there
00213     // might be a child transaction outside this process
00214     if(!childrenExist()) {
00215       myarmsdk_correlator_setenv(&m_tranCorr);
00216     }
00217   } // end if
00218 }
00219 
00220 /*--------------------------------------------------------------------------*/
00221 
00222 void QArmTransaction::stop(const QArmTransaction::QArmStatus status) {
00223   
00224   if(m_active) {
00225       
00226     emit stopped(status);
00227       
00228     arm_stop_transaction(m_tranHandle,
00229                          static_cast<arm_tran_status_t>(status),
00230                          ARM_FLAG_NONE,
00231                          ARM_BUF4_NONE);
00232       
00233     // Make the external correlator the current correlator for followup
00234     // transactions, but only in case there is no internal parent.
00235     if(m_tranParent == 0) {
00236       myarmsdk_correlator_setenv(m_parentCorr);
00237     }
00238     else if(!childrenExist()) {
00239       // In this case the current correlator was set as environment variable.
00240       // This variable has to be reset.
00241         myarmsdk_correlator_setenv(ARM_CORR_NONE);
00242     }
00243 
00244     m_active = false;
00245   }
00246 }
00247 
00248 /*--------------------------------------------------------------------------*/
00249 
00250 char *QArmTransaction::getStringifiedCorrelator(char *corrstr, 
00251                                                 size_t size) const {
00252 
00253   const arm_correlator_t *c = getCorrelator();
00254   char *ret = NULL;
00255 
00256   if(c != ARM_CORR_NONE) {
00257     if(-1 != myarmsdk_correlator_stringify(MYARMSDK_CORR_HEX_NO_HEADER,
00258                                            c,
00259                                            corrstr, 
00260                                            size)) {
00261       ret = corrstr;
00262     }
00263   }
00264   return ret;
00265 }

Generated on Thu Dec 15 19:14:20 2005 for QArm API by  doxygen 1.4.2