You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@etch.apache.org by jd...@apache.org on 2009/04/22 19:25:51 UTC

svn commit: r767594 [42/43] - in /incubator/etch/trunk/binding-c/runtime/c: ./ ext/ ext/hashtab/ ext/lib/ inc/ lib/ project/ project/$etchstop/ project/bin/ project/etch/ project/logcli/ project/logsrv/ project/notes/ project/test/ project/test/logcli/...

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_client.c
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_client.c?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_client.c (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_client.c Wed Apr 22 17:25:43 2009
@@ -0,0 +1,92 @@
+/* $Id$ 
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
+ * contributor license agreements. See the NOTICE file distributed with  
+ * this work for additional information regarding copyright ownership. 
+ * The ASF licenses this file to you under the Apache License, Version  
+ * 2.0 (the "License"); you may not use this file except in compliance  
+ * with the License. You may obtain a copy of the License at 
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License. 
+ */ 
+
+/*
+ * xmpl_perf_remote_client.c
+ */
+
+#include "apr_time.h" /* some apr must be included first */
+#include "xmpl_perf_remote_client.h"
+#include "etch_global.h"
+#include "etch_url.h" 
+#include "etchlog.h" 
+
+#include <tchar.h>
+#include <stdio.h>
+#include <conio.h>
+char* ETCHREMC = "REMC";
+
+/* generated signatures */
+int destroy_perf_remote_client (perf_remote_client*);
+
+
+/* - - - - - - - -    
+ * instantiation
+ * - - - - - - - -   
+ */
+
+/**
+ * new_remote_client()
+ * perf_remote_client constructor.
+ */
+perf_remote_client* new_remote_client (void* thisx, etch_session* session, etch_value_factory* vf)
+{
+    perf_remote* remote = NULL;
+    perf_remote_client* rc = NULL;
+
+    rc = (perf_remote_client*) new_object (sizeof(perf_remote_client), 
+       ETCHTYPEB_REMOTECLIENT, get_dynamic_classid_unique(&CLASSID_PERFREMOTECLIENT));
+
+    rc->destroy = destroy_perf_remote_client;
+
+    /* we "implement" the service interface here since it may contain client-directed 
+     * items, in which case those methods and data are exposed in this object.  we do  
+     * not expose the service's server-directed methods in the remote client object.
+     */
+    remote = new_perf_remote (thisx, session->ds, vf, NULL);
+    remote->remote_type = ETCH_REMOTETYPE_CLIENT;
+
+    rc->perf_remote_base = remote;
+    rc->perf_client_base = new_perf_client_base (thisx, remote->iperf);
+    rc->session_id = session->session_id;
+
+    /* override client-directed virtuals with implementations here */
+    /* no toward-client items are declared by this service */
+
+    return rc;
+}
+
+
+/**
+ * destroy_perf_remote_client()
+ * perf_remote_client destructor.
+ */
+int destroy_perf_remote_client (perf_remote_client* thisx)
+{
+    if (NULL == thisx) return -1;
+    if (thisx->refcount > 0 && --thisx->refcount > 0) return -1;  
+
+    if (!is_etchobj_static_content(thisx))
+    {    
+        ETCHOBJ_DESTROY(thisx->perf_remote_base);
+        ETCHOBJ_DESTROY(thisx->perf_client_base);
+    }
+            
+    return destroy_objectex((objmask*)thisx);
+}
+

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_client.h
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_client.h?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_client.h (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_client.h Wed Apr 22 17:25:43 2009
@@ -0,0 +1,74 @@
+/* $Id$ 
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
+ * contributor license agreements. See the NOTICE file distributed with  
+ * this work for additional information regarding copyright ownership. 
+ * The ASF licenses this file to you under the Apache License, Version  
+ * 2.0 (the "License"); you may not use this file except in compliance  
+ * with the License. You may obtain a copy of the License at 
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License. 
+ */ 
+
+/*
+ * xmpl_perf_remote_client.h 
+ */
+
+#ifndef PERF_REMOTE_CLIENT_H
+#define PERF_REMOTE_CLIENT_H
+
+#include "xmpl_perf_remote.h"
+#include "xmpl_perf_client.h"
+#include "etch_transport.h"
+
+unsigned short CLASSID_PERFREMOTECLIENT;
+
+
+/**
+ * perf_remote_client
+ */
+typedef struct perf_remote_client
+{
+    unsigned int    hashkey;  
+    unsigned short  obj_type; 
+    unsigned short  class_id;
+    struct objmask* vtab;  
+    int  (*destroy)(void*);
+    void*(*clone)  (void*); 
+    obj_gethashkey  get_hashkey;
+    struct objmask* parent;
+    etchresult*     result;
+    unsigned int    refcount;
+    unsigned int    length;
+    unsigned char   is_null;
+    unsigned char   is_copy;
+    unsigned char   is_static;
+    unsigned char   reserved;
+
+    i_perf_client* perf_client_base;     /* owned */
+    perf_remote*   perf_remote_base;     /* owned */
+    etch_server_factory* server_factory; /* owned */
+    default_value_factory* vf;   /* owned by base */
+    int session_id;
+
+    /* toward-client virtuals go here */
+    /* no toward-client items are declared by this service */
+
+    /* asyncs go here if any toward-client messages defined */
+
+} perf_remote_client;
+
+
+
+/* constructor */
+perf_remote_client* new_remote_client (void*, etch_session*, etch_value_factory*);
+
+
+#endif /* PERF_REMOTE_CLIENT_H */
+

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_server.c
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_server.c?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_server.c (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_server.c Wed Apr 22 17:25:43 2009
@@ -0,0 +1,757 @@
+/* $Id$ 
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
+ * contributor license agreements. See the NOTICE file distributed with  
+ * this work for additional information regarding copyright ownership. 
+ * The ASF licenses this file to you under the Apache License, Version  
+ * 2.0 (the "License"); you may not use this file except in compliance  
+ * with the License. You may obtain a copy of the License at 
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License. 
+ */ 
+
+/*
+ * xmpl_perf_remote_server.c
+ * generated remote procedure calls.
+ */
+
+#include "apr_time.h" /* some apr must be included first */
+#include "xmpl_perf_remote_server.h"
+#include "etch_plainmboxmgr.h"
+#include "etch_svcobj_masks.h"
+#include "etch_global.h"
+#include "etchexcp.h"
+#include "etch_url.h" 
+#include "etchlog.h" 
+
+#include <tchar.h>
+#include <stdio.h>
+#include <conio.h>
+char* ETCHREMS = "REMS";
+
+i_mailbox*  perf_remote_add_begin (perf_remote_server*, etch_int32*, etch_int32*);
+etch_int32* perf_remote_add_end   (perf_remote_server*, i_mailbox*);
+etch_int32* perf_remote_add       (perf_remote_server*, etch_int32*, etch_int32*);
+i_mailbox*  perf_remote_sum_begin (perf_remote_server*, etch_arraytype*);
+etch_int32* perf_remote_sum_end   (perf_remote_server*, i_mailbox*);
+etch_int32* perf_remote_sum       (perf_remote_server*, etch_arraytype*);
+i_mailbox*  perf_remote_dist_begin(perf_remote_server*, perf_point*, perf_point*);
+perf_point* perf_remote_dist_end  (perf_remote_server*, i_mailbox*);
+perf_point* perf_remote_dist      (perf_remote_server*, perf_point*, perf_point*);
+i_mailbox*  perf_remote_add2_begin(perf_remote_server*, etch_date* objdate, etch_int64*);
+etch_date*  perf_remote_add2_end  (perf_remote_server*, i_mailbox*);
+etch_date*  perf_remote_add2      (perf_remote_server*, etch_date* objdate, etch_int64*);
+void* perf_remote_report  (perf_remote_server*, etch_int32*, etch_string*);
+void* perf_remote_report2 (perf_remote_server*, etch_date*, etch_int32*, etch_string*);
+int destroy_perf_remote_server (perf_remote_server*);
+
+
+/* - - - - - - - - - -   
+ * instantiation etc.
+ * - - - - - - - - - -  
+ */
+
+/**
+ * new_perf_remote_server()
+ * perf_remote_server constructor.
+ * @param thisx owner, optional, null in practice.
+ * @param ids delivery service interface, caller retains.
+ * @param vf service specific value factory, caller retains.
+ */
+perf_remote_server* new_perf_remote_server (void* thisx, i_delivery_service* ids, etch_value_factory* vf)
+{
+    perf_remote_server* rs = (perf_remote_server*) new_object (sizeof(perf_remote_server), 
+        ETCHTYPEB_REMOTESERVER, get_dynamic_classid_unique(&CLASSID_PERFREMOTESERVER));
+
+    rs->destroy = destroy_perf_remote_server;
+
+    rs->remote_base = new_perf_remote (thisx, ids, vf, NULL);
+    rs->remote_base->remote_type = ETCH_REMOTETYPE_SERVER;
+
+    /* 2/3/09 now passing perf interface not owned by server_base */
+    rs->server_base = new_perf_remote_server_base (thisx, rs->remote_base->iperf);  
+
+    rs->vf = (perf_value_factory*) rs->remote_base->vf;
+
+    rs->add  = perf_remote_add;
+    rs->sum  = perf_remote_sum;
+    rs->dist = perf_remote_dist;
+    rs->add2 = perf_remote_add2;
+    rs->report  = perf_remote_report;
+    rs->report2 = perf_remote_report2;
+
+    rs->async_begin_add = perf_remote_add_begin;
+    rs->async_end_add   = perf_remote_add_end;
+    rs->async_begin_sum = perf_remote_sum_begin;
+    rs->async_end_sum   = perf_remote_sum_end;
+    rs->async_begin_dist= perf_remote_dist_begin;
+    rs->async_end_dist  = perf_remote_dist_end;
+    rs->async_begin_add2= perf_remote_add2_begin;
+    rs->async_end_add2  = perf_remote_add2_end;
+
+    return rs;
+}
+
+
+/**
+ * destroy_perf_server_base()
+ * i_perf_server destructor.
+ */
+int destroy_perf_remote_server (perf_remote_server* thisx)
+{
+    if (NULL == thisx) return -1;
+    if (thisx->refcount > 0 && --thisx->refcount > 0) return -1;  
+
+    if (!is_etchobj_static_content(thisx))
+    {    
+        ETCHOBJ_DESTROY(thisx->remote_base);
+        ETCHOBJ_DESTROY(thisx->server_base);
+        ETCHOBJ_DESTROY(thisx->client_factory);
+    }
+            
+    return destroy_objectex((objmask*)thisx);
+}
+
+
+/**
+ * perf_remote_dispose_mailbox()
+ * dispose of mailbox after use.
+ * this is the common means of disposing of a mailbox when we're done with it.
+ * this would intuitively be part of base class code but we don't have one.
+ * @param thisx the remote server this.
+ * @param pibox pointer to pointer to the mailbox interface, passed indirectly
+ * such that this method can null out the caller's mailbox reference.
+ * @return 0 if mailbox was successfullly closed, otherwise -1. 
+ * caller's i_mailbox reference is nulled out regardless of result.
+ */
+int perf_remote_dispose_mailbox (perf_remote_server* thisx, i_mailbox** pibox)
+{
+    int result = 0;
+    i_mailbox* ibox = 0;
+    if (!pibox || !*pibox) return -1;
+    ibox = *pibox;
+    *pibox = NULL;  /* null out caller's reference */
+    
+    if (0 != (result = ibox->close_read (ibox)))
+    {  
+        /* we should not need this failsafe unregister if close_read() 
+         * is reliable, since close_read() will do the unregister */
+        i_mailbox_manager* imgr = ibox->manager(ibox);
+        etchlog(ETCHREMS, ETCHLOG_ERROR, "could not close mailbox %x\n", ibox);
+        if (imgr) result = imgr->unregister(imgr, ibox);
+    }
+ 
+    /* mailbox manager does not destroy the unregistered mailbox since it is    
+     * owned by whoever registered it, that being us, so we destroy it here. 
+     * debug heap issue note: this is/was the spot.
+     */
+    ibox->destroy(ibox);   
+    return result;
+}
+
+
+/**
+ * perf_remote_resultobj()
+ * check result of remote call and throw exception if indicated.
+ * @param obj the result object of the remote call.
+ * @param result the result code.
+ * @param idtext textual indicator of the message in progress.
+ * @return a non-null objmask* based object possibly wrapping an exception.
+ * @remarks using this method to return the result from all remote calls 
+ * ensures both that a null object is never returned to the application,
+ * and that an exception is always present for a bad result code. 
+ */
+void* perf_remote_resultobj (void* obj, int result, wchar_t* caller)
+{
+    objmask* resultobj = obj? obj: (objmask*) new_int32(result);
+
+    /* if bad result and exception not already present, throw one */
+    if ((result || !obj) && !is_exception(resultobj))
+        etch_throw(resultobj, EXCPTYPE_INTERNALERR, caller, ETCHEXCP_COPYTEXT);
+
+    return resultobj;
+}
+
+
+/**
+ * perf_remote_get_stubbase()
+ * convenience to return stub base object from remote server object.
+ */
+etch_stub* perf_remote_get_stubbase (perf_remote_server* rs)
+{
+    etch_stub* stub = NULL;
+    xxxx_either_stub* perf_clistub = (xxxx_either_stub*) rs->client_factory->stub;
+    stub = perf_clistub? perf_clistub->stub_base: NULL;
+    return stub;
+}
+
+
+/**
+ * perf_remote_set_session_notify()
+ * convenience to override remote server's session_notify().
+ * @return the session_notify function that was overridden.
+ */
+etch_session_notify perf_remote_set_session_notify 
+    (perf_remote_server* rs, etch_session_notify newfunc)
+{
+    etch_session_notify oldfunc = NULL;
+    etch_stub* stub = perf_remote_get_stubbase(rs);
+    if (NULL == stub || NULL == stub->impl_callbacks) return NULL;
+    oldfunc = stub->impl_callbacks->_session_notify;
+    stub->impl_callbacks->_session_notify = newfunc;
+    return oldfunc;
+}
+
+
+/**
+ * perf_remote_set_session_control()
+ * convenience to override remote server's session_control().
+ * @return the session_control function that was overridden.
+ */
+etch_session_control perf_remote_set_session_control 
+    (perf_remote_server* rs, etch_session_control newfunc)
+{
+    etch_session_control oldfunc = NULL;
+    etch_stub* stub = perf_remote_get_stubbase(rs);
+    if (NULL == stub || NULL == stub->impl_callbacks) return NULL;
+    oldfunc = stub->impl_callbacks->_session_control;
+    stub->impl_callbacks->_session_control = newfunc;
+    return oldfunc;
+}
+
+
+/**
+ * perf_remote_set_session_query()
+ * convenience to override remote server's session_query().
+ * @return the session_query function that was overridden.
+ */
+etch_session_query perf_remote_set_session_query 
+    (perf_remote_server* rs, etch_session_query newfunc)
+{
+    etch_session_query oldfunc = NULL;
+    etch_stub* stub = perf_remote_get_stubbase(rs);
+    if (NULL == stub || NULL == stub->impl_callbacks) return NULL;
+    oldfunc = stub->impl_callbacks->_session_query;
+    stub->impl_callbacks->_session_query = newfunc;
+    return oldfunc;
+}
+
+
+/* - - - - - - - - - - - - - - - - - - - -  
+ * remote procedure call implementations
+ * - - - - - - - - - - - - - - - - - - - - 
+ */
+ 
+/* - - - - - - - - - - -  
+ * perf.add()
+ * - - - - - - - - - - -  
+ */
+
+/**
+ * perf_remote_add_begin()
+ * perf.add async start 
+ * @param thisx this.
+ * @param x etch_int32* caller relinquishes.
+ * @param y etch_int32* caller relinquishes.
+ * @return mailbox to receive async result. caller owns it. it may be null.
+ * @remarks note that we use the putc version of message.put(), wherein we pass
+ * a *reference* to the value object's pointer, and message.putc() nulls out  
+ * the reference. this permits us to break when a putc() error occurs, without  
+ * leaking the un-put parameters, since prior to exit we can destroy each 
+ * parameter which remains non-null.
+ * @remarks note also that we don't bother to clone the value keys, since they  
+ * are protected objects, and while message_put will appear to destroy them,
+ * this will have no effect.
+ */
+i_mailbox* perf_remote_add_begin (perf_remote_server* thisx, etch_int32* x, etch_int32* y)
+{
+    int result = 0;
+    i_mailbox* mbox = NULL;
+    etch_message* msg = NULL;
+    etch_type* msgtype = _g_perf_statics->_mt_etch_xmpl_perfserver_add;
+
+    do
+    {   msg = thisx->remote_base->new_message (thisx->remote_base, msgtype);
+        if (!msg) break;
+
+        result = message_putc (msg, _g_perf_statics->_mf_x, &x);
+        if (0 != result) break;  /* see putc() comments above */
+        result = message_putc (msg, _g_perf_statics->_mf_y, &y);
+        if (0 != result) break;      
+
+        /* fyi msg memory is relinquished here regardless of result */ 
+        result = thisx->remote_base->begin_call (thisx->remote_base, msg, &mbox);
+        msg = NULL;
+
+    } while(0);
+
+    /* destroy any unrelinquished objects */
+    ETCHOBJ_DESTROY(x); 
+    ETCHOBJ_DESTROY(y);
+    ETCHOBJ_DESTROY(msg); 
+    return mbox;
+}
+
+
+/**
+ * perf_remote_add_end()
+ * add async end (read result from mailbox and return result)
+ * @param thisx this.
+ * @param mbox caller relinquishes
+ * @return etch_int32* result of add, caller owns.
+ */
+etch_int32* perf_remote_add_end (perf_remote_server* thisx, i_mailbox* ibox)
+{
+    etch_int32* resobj = NULL;
+    etch_type* restype = _g_perf_statics->_mt_etch_xmpl_perfclient_result_add;
+
+    const int result = thisx->remote_base->end_call 
+        (thisx->remote_base, ibox, restype, &resobj);
+
+    return resobj;
+}
+
+
+/**
+ * perf_remote_add()
+ * perf.add remote method call.
+ * instantiates a mailbox, sends perf.add message, waits for result to arrive
+ * in mailbox, disposes mailbox, and returns object containing add() result.
+ * @param thisx this.
+ * @param x etch_int32* caller relinquishes.
+ * @param y etch_int32* caller relinquishes.
+ * @return etch_int32* result of add, caller owns.
+ */
+etch_int32* perf_remote_add (perf_remote_server* thisx, etch_int32* x, etch_int32* y)
+{
+    int result = -1;
+    etch_int32* resultobj = NULL;
+
+    i_mailbox* mbox = perf_remote_add_begin (thisx, x, y);
+    
+    if (mbox)
+    {   // TESTING NOTE we can comment out the add_end() to no ill effect
+        resultobj = perf_remote_add_end (thisx, mbox);  
+    
+        result = perf_remote_dispose_mailbox (thisx, &mbox);   
+    }
+
+    return perf_remote_resultobj (resultobj, result, L"perf.add");
+}
+
+ 
+/* - - - - - - - - - - -  
+ * perf.sum()
+ * - - - - - - - - - - -  
+ */
+
+/**
+ * perf_remote_sum_begin()
+ * sum async start 
+ * @param thisx this.
+ * @param an etch_nativearray or etch_arrayvalue, caller relinquishes.
+ * @return a mailbox, caller owns it. may be null.
+ */
+i_mailbox* perf_remote_sum_begin (perf_remote_server* thisx, etch_arraytype* a)
+{
+    int result = 0;
+    i_mailbox* mbox = NULL;
+    etch_message* msg = NULL;
+    etch_type* msgtype = _g_perf_statics->_mt_etch_xmpl_perfserver_sum;
+
+    do
+    {   msg = thisx->remote_base->new_message (thisx->remote_base, msgtype);
+        if (!msg) break;
+
+        result = message_putc (msg, _g_perf_statics->_mf_values, &a);
+        if (0 != result) break;  /* see earlier putc() comments */
+    
+        /* fyi msg memory is relinquished here regardless of result */ 
+        result = thisx->remote_base->begin_call (thisx->remote_base, msg, &mbox);
+        msg = NULL;
+
+    } while(0);
+
+    /* destroy any unrelinquished objects */
+    ETCHOBJ_DESTROY(a); 
+    ETCHOBJ_DESTROY(msg); 
+    return mbox;
+}
+
+
+/**
+ * perf_remote_sum_end()
+ * sum async end (read result from mailbox and return result)
+ * @param thisx this.
+ * @param mbox caller relinquishes
+ * @return etch_int32* result of sum, caller owns.
+ */
+etch_int32* perf_remote_sum_end (perf_remote_server* thisx, i_mailbox* mbox)
+{
+    etch_int32* resobj = NULL;
+    etch_type*  restype = _g_perf_statics->_mt_etch_xmpl_perfclient_result_add;
+
+    const int result = thisx->remote_base->end_call 
+        (thisx->remote_base, mbox, restype, &resobj);
+     
+    return resobj;
+}
+
+
+/**
+ * perf_remote_sum()
+ * perf.sum remote method call.
+ * instantiates a mailbox, sends perf.sum message, waits for result to arrive
+ * in mailbox, disposes mailbox, and returns object containing sum() result.
+ * @param thisx this.
+ * @param a an etch_nativearray or etch_arrayvalue, caller relinquishes.
+ * @return etch_int32* result of sum, caller owns.
+ */
+etch_int32* perf_remote_sum (perf_remote_server* thisx, etch_arraytype* a)
+{
+    etch_int32* resultobj = NULL;
+
+    i_mailbox* mbox = perf_remote_sum_begin (thisx, a);
+    
+    if (mbox) 
+    {   resultobj = perf_remote_sum_end (thisx, mbox);  
+    
+        perf_remote_dispose_mailbox (thisx, &mbox);
+    }
+
+    return perf_remote_resultobj (resultobj, 0, L"perf.sum");
+}
+
+ 
+/* - - - - - - - - - - -  
+ * perf.report()
+ * - - - - - - - - - - -  
+ */
+
+/**
+ * perf_remote_report_begin()
+ * report() execution (one-way, no async result ergo no mailbox)
+ * @param thisx this.
+ * @param code an etch integer, caller relinquishes.
+ * @param x etch_string caller relinquishes.
+ * @return etch_int32 wrapping the remote send result code, and if that result  
+ * was non-zero, also wrapping an exception object. 
+ */
+void* perf_remote_report_begin (perf_remote_server* thisx, etch_int32* code, etch_string* x)
+{
+    int result = 0;
+    etch_message* msg = NULL;
+    etch_int32* resultobj = NULL;
+    etch_type* msgtype = _g_perf_statics->_mt_etch_xmpl_perfserver_report;
+
+    do
+    {   msg = thisx->remote_base->new_message (thisx->remote_base, msgtype);
+        if (!msg) break;
+
+        result = message_putc (msg, _g_perf_statics->_mf_code, &code);
+        if (0 != result) break;  /* see earlier putc() comments */
+        result = message_putc (msg, builtins._mf_msg, &x);
+        if (0 != result) break; 
+
+        /* fyi msg memory is relinquished here regardless of result */ 
+        resultobj = thisx->remote_base->sendex (thisx->remote_base, msg);
+        msg = NULL;
+      
+    } while(0);
+
+    /* destroy any unrelinquished objects */
+    ETCHOBJ_DESTROY(code); 
+    ETCHOBJ_DESTROY(x); 
+    ETCHOBJ_DESTROY(msg); 
+    return resultobj;
+}
+
+
+/**
+ * perf_remote_report_end()
+ * async result handler not used since perf.report is a one-way send-and-forget method.
+ */
+void* perf_remote_report_end (perf_remote_server* thisx, i_mailbox* mbox)
+{
+    return NULL;
+}
+
+
+/**
+ * perf_remote_report()
+ * perf.report remote 1-way method call.
+ * sends perf.report message and does not wait for a result. if server implementation
+ * code throws an exception, the exception arrives via session_notify override if any.
+ * @param code an integer object, caller relinquishes.
+ * @param x etch_string caller relinquishes.
+ * @return integer transport result code cast to void*.
+ */
+void* perf_remote_report (perf_remote_server* thisx, etch_int32* code, etch_string* x)
+{
+    /* perf.report is a one-way, send-and-forget message so we only do a begin call */
+    void* resultobj = perf_remote_report_begin (thisx, code, x);
+    
+    return perf_remote_resultobj (resultobj, 0, L"perf.report");
+}
+
+
+/* - - - - - - - - - - -  
+ * perf.dist()
+ * - - - - - - - - - - -  
+ */
+
+/**
+ * perf_remote_dist_begin()
+ * dist async start 
+ * @param thisx this.
+ * @param p1 etch_point* caller relinquishes.
+ * @param p2 etch_point* caller relinquishes.
+ * @return mailbox to receive async result. caller owns it. may be null.
+ */
+i_mailbox* perf_remote_dist_begin (perf_remote_server* thisx, perf_point* p1, perf_point* p2)
+{
+    i_mailbox* mbox = NULL;
+    etch_message* msg = NULL;
+    int result = -1, is_argerr = !p1 || !p2;
+    etch_type* msgtype = _g_perf_statics->_mt_etch_xmpl_perfserver_dist;
+
+    do
+    {   msg = thisx->remote_base->new_message (thisx->remote_base, msgtype);
+        if (!msg) break;
+
+        result = message_putc (msg, _g_perf_statics->_mf_a, &p1);
+        if (0 != result) break; /* see earlier putc() comments */
+        result = message_putc (msg, _g_perf_statics->_mf_b, &p2);
+        if (0 != result) break;       
+
+        /* fyi msg memory is relinquished here regardless of result */ 
+        result = thisx->remote_base->begin_call (thisx->remote_base, msg, &mbox);
+        msg = NULL;
+
+    } while(0);
+
+    /* destroy any unrelinquished objects */
+    ETCHOBJ_DESTROY(p1);
+    ETCHOBJ_DESTROY(p2);
+    ETCHOBJ_DESTROY(msg);
+    return mbox;
+}
+
+
+/**
+ * perf_remote_dist_end()
+ * dist async end (read result from mailbox and return result)
+ * @param thisx this.
+ * @param mbox caller relinquishes
+ * @return etch_point* result of dist, caller owns.
+ */
+perf_point* perf_remote_dist_end (perf_remote_server* thisx, i_mailbox* mbox)
+{
+    perf_point* resobj = NULL;
+    etch_type*  restype = _g_perf_statics->_mt_etch_xmpl_perfclient_result_dist;
+
+    const int result = thisx->remote_base->end_call 
+        (thisx->remote_base, mbox, restype, &resobj);
+
+    return resobj;
+}
+
+
+/**
+ * perf_remote_dist()
+ * perf.dist remote method call.
+ * instantiates a mailbox, sends perf.dist message, waits for result to arrive
+ * in mailbox, disposes mailbox, and returns object containing dist() result.
+ * @param thisx this.
+ * @param x etch_int32* caller relinquishes.
+ * @param y etch_int32* caller relinquishes.
+ * @return etch_int32* result of dist, caller owns.
+ */
+perf_point* perf_remote_dist (perf_remote_server* thisx, perf_point* p1, perf_point* p2)
+{
+    perf_point* resultobj = NULL;
+    int result = -1;
+
+    i_mailbox* mbox = perf_remote_dist_begin (thisx, p1, p2);
+    
+    if (mbox) 
+    {   resultobj = perf_remote_dist_end (thisx, mbox);  
+    
+        result = perf_remote_dispose_mailbox (thisx, &mbox);
+    }
+
+    return perf_remote_resultobj (resultobj, result, L"perf.dist");
+}
+
+
+/* - - - - - - - - - - -  
+ * perf.add2()
+ * - - - - - - - - - - -  
+ */
+
+/**
+ * perf_remote_add2_begin()
+ * add2 async start 
+ * @param thisx this.
+ * @param objdate etch_date* caller relinquishes.
+ * @param objms etch_int64* caller relinquishes.
+ * @return mailbox to receive async result. caller owns it. may be null.
+ */
+i_mailbox* perf_remote_add2_begin (perf_remote_server* thisx, etch_date* objdate, etch_int64* objms)
+{
+    int result = 0;
+    i_mailbox* mbox = NULL;
+    etch_message* msg = NULL;
+    etch_type* msgtype = _g_perf_statics->_mt_etch_xmpl_perfserver_add2;
+
+    do
+    {   msg = thisx->remote_base->new_message (thisx->remote_base, msgtype);
+        if (!msg) break;
+
+        result = message_putc (msg, _g_perf_statics->_mf_ts, &objdate);
+        if (0 != result) break;  /* see earlier putc() comments */
+        result = message_putc (msg, _g_perf_statics->_mf_ms, &objms);
+        if (0 != result) break;        
+
+        /* fyi msg memory is relinquished here regardless of result */ 
+        result = thisx->remote_base->begin_call (thisx->remote_base, msg, &mbox);
+        msg = NULL;
+
+    } while(0);
+
+    /* destroy any unrelinquished objects */
+    ETCHOBJ_DESTROY(objdate);
+    ETCHOBJ_DESTROY(objms); 
+    ETCHOBJ_DESTROY(msg);
+    return mbox;
+}
+
+
+/**
+ * perf_remote_add2_end()
+ * add2 async end (read result from mailbox and return result)
+ * @param thisx this.
+ * @param mbox caller relinquishes
+ * @return etch_point* result of add2, caller owns.
+ */
+etch_date* perf_remote_add2_end (perf_remote_server* thisx, i_mailbox* mbox)
+{
+    int result = 0;
+    etch_date* resobj = NULL;
+    etch_type* restype = _g_perf_statics->_mt_etch_xmpl_perfclient_result_add2;
+
+    result = thisx->remote_base->end_call (thisx->remote_base, mbox, restype, &resobj);
+
+    return resobj;
+}
+
+
+/**
+ * perf_remote_add2()
+ * perf.add2 remote method call.
+ * instantiates a mailbox, sends perf.add2 message, waits for result to arrive
+ * in mailbox, disposes mailbox, and returns object containing add2() result.
+ * @param thisx this.
+ * @param objdate etch_date* caller relinquishes.
+ * @param objms etch_int64* caller relinquishes.
+ * @return etch_date* result of add2, caller owns.
+ */
+etch_date* perf_remote_add2 (perf_remote_server* thisx, etch_date* objdate, etch_int64* objms)
+{
+    etch_date* resultobj = NULL;
+    int result = -1;
+
+    i_mailbox* mbox = perf_remote_add2_begin (thisx, objdate, objms);
+    
+    if (mbox)  
+    {
+        resultobj = perf_remote_add2_end (thisx, mbox);  
+    
+        result = perf_remote_dispose_mailbox (thisx, &mbox);
+    }
+
+    return perf_remote_resultobj (resultobj, result, L"perf.add2");
+}
+
+ 
+/* - - - - - - - - - - -  
+ * perf.report2()
+ * - - - - - - - - - - -  
+ */
+
+/**
+ * perf_remote_report2_begin()
+ * report2() execution (one-way, no async result ergo no mailbox)
+ * @param thisx this.
+ * @param ts etch_date*, caller relinquishes.
+ * @param n an integer object, caller relinquishes.
+ * @param x etch_string caller relinquishes.
+ * @return etch_int32 wrapping the remote send result code, and if that result  
+ * was non-zero, also wrapping an exception object. 
+ */
+void* perf_remote_report2_begin (perf_remote_server* thisx, etch_date* ts, etch_int32* n, etch_string* x)
+{
+    int result = 0;
+    etch_message* msg = NULL;
+    etch_int32* resultobj = NULL;
+    etch_type* msgtype = _g_perf_statics->_mt_etch_xmpl_perfserver_report2;
+
+    do
+    {   msg = thisx->remote_base->new_message (thisx->remote_base, msgtype);
+        if (!msg) break;
+
+        result = message_putc (msg, _g_perf_statics->_mf_ts, &ts);
+        if (0 != result) break;  /* see earlier putc() comments */
+        result = message_putc (msg, _g_perf_statics->_mf_code, &n);
+        if (0 != result) break;  
+        result = message_putc (msg, builtins._mf_msg, &x);
+        if (0 != result) break; 
+
+        /* msg memory is relinquished here regardless of result */ 
+        resultobj = thisx->remote_base->sendex (thisx->remote_base, msg);
+        msg = NULL;
+
+    } while(0);
+
+    /* destroy any unrelinquished objects */
+    ETCHOBJ_DESTROY(ts); 
+    ETCHOBJ_DESTROY(n); 
+    ETCHOBJ_DESTROY(x); 
+    ETCHOBJ_DESTROY(msg);
+    return resultobj;
+}
+
+
+/**
+ * perf_remote_report2_end()
+ * not used.
+ */
+void* perf_remote_report2_end (perf_remote_server* thisx, i_mailbox* mbox)
+{
+    return NULL;
+}
+
+
+/**
+ * perf_remote_report2()
+ * perf.report2 remote 1-way method call.
+ * sends perf.report2 message and does not wait for a result. if server implementation
+ * code throws an exception, the exception arrives via session_notify override if any.  
+ * @param ts etch_date*, caller relinquishes
+ * @param n an integer object, caller relinquishes.
+ * @param x etch_string caller relinquishes.
+ * @return integer transport result code cast to void*.
+ */
+void* perf_remote_report2 (perf_remote_server* thisx, etch_date* ts, etch_int32* n, etch_string* x)
+{
+    /* perf.report2 is a one-way, send-and-forget message so we only do a begin call */
+    void* resultobj = perf_remote_report2_begin (thisx, ts, n, x);
+    
+    return perf_remote_resultobj (resultobj, 0, L"perf.report2");
+}

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_server.h
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_server.h?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_server.h (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_remote_server.h Wed Apr 22 17:25:43 2009
@@ -0,0 +1,100 @@
+/* $Id$ 
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
+ * contributor license agreements. See the NOTICE file distributed with  
+ * this work for additional information regarding copyright ownership. 
+ * The ASF licenses this file to you under the Apache License, Version  
+ * 2.0 (the "License"); you may not use this file except in compliance  
+ * with the License. You may obtain a copy of the License at 
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License. 
+ */ 
+
+/*
+ * xmpl_perf_remote_server.h 
+ * generated remote procedure calls.
+ */
+
+#ifndef PERF_REMOTE_SERVER_H
+#define PERF_REMOTE_SERVER_H
+
+#include "xmpl_perf_remote.h"
+#include "xmpl_perf_server.h"
+#include "xmpl_perf_valufact.h"
+#include "etch_transport.h"      
+
+unsigned short CLASSID_PERFREMOTESERVER;
+
+
+/**
+ * perf_remote_server
+ */
+typedef struct perf_remote_server
+{
+    unsigned int    hashkey;  
+    unsigned short  obj_type; 
+    unsigned short  class_id;
+    struct objmask* vtab;  
+    int  (*destroy)(void*);
+    void*(*clone)  (void*); 
+    obj_gethashkey  get_hashkey;
+    struct objmask* parent;
+    etchresult*     result;
+    unsigned int    refcount;
+    unsigned int    length;
+    unsigned char   is_null;
+    unsigned char   is_copy;
+    unsigned char   is_static;
+    unsigned char   reserved;
+
+    i_perf_server* server_base;  /* owned */
+    perf_remote*   remote_base;  /* owned */
+    etch_client_factory* client_factory; /* owned */
+    perf_value_factory*  vf;     /* owned by base */
+    int server_id;
+
+    perf_add       add;
+    perf_sum       sum;
+    perf_report    report;
+    perf_dist      dist;
+    perf_add2      add2;
+    perf_report2   report2;
+
+    perf_point*    point;
+               
+    /* private, generally. since unit tests invoke async begin and end,
+     * we must expose them either as virtuals or as external references.
+     */           
+    perf_async_begin_add    async_begin_add; 
+    perf_async_begin_sum    async_begin_sum;
+    perf_async_begin_dist   async_begin_dist;
+    perf_async_begin_add2   async_begin_add2;
+     
+    perf_async_end_add      async_end_add;
+    perf_async_end_sum      async_end_sum;
+    perf_async_end_dist     async_end_dist;
+    perf_async_end_add2     async_end_add2;
+
+} perf_remote_server;
+
+
+/* constructor */
+perf_remote_server* new_perf_remote_server (void*, i_delivery_service*, etch_value_factory*);
+
+int perf_remote_dispose_mailbox(perf_remote_server*, i_mailbox**);
+
+/* convenience methods to override client's session interface methods */
+etch_stub* perf_remote_get_stubbase (perf_remote_server*);
+etch_session_notify  perf_remote_set_session_notify( perf_remote_server*, etch_session_notify);
+etch_session_control perf_remote_set_session_control(perf_remote_server*, etch_session_control);
+etch_session_query   perf_remote_set_session_query  (perf_remote_server*, etch_session_query);
+
+
+#endif /* PERF_REMOTE_SERVER_H */
+

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server.c
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server.c?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server.c (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server.c Wed Apr 22 17:25:43 2009
@@ -0,0 +1,140 @@
+/* $Id$ 
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
+ * contributor license agreements. See the NOTICE file distributed with  
+ * this work for additional information regarding copyright ownership. 
+ * The ASF licenses this file to you under the Apache License, Version  
+ * 2.0 (the "License"); you may not use this file except in compliance  
+ * with the License. You may obtain a copy of the License at 
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License. 
+ */ 
+
+/*
+ * xmpl_perf_server.c 
+ */
+
+#include "apr_time.h" /* some apr must be included first */
+#include "xmpl_perf_server.h"
+#include "etch_global.h"
+#include "etch_url.h"  
+
+#include <tchar.h>
+#include <stdio.h>
+#include <conio.h>
+
+int destroy_perf_server_via_base (i_perf_server*);
+
+
+/* - - - - - - - - - - - - - -  
+ * constructors
+ * - - - - - - - - - - - - - -  
+ */
+
+/**
+ * new_perf_server_base()  
+ * @param implobj not interpreted
+ * @param psi a perf service interface. if supplied, caller retains,
+ * otherwise a service interface is instantiated and owned here. 
+ */
+i_perf_server* new_perf_server_base (void* implobj, i_perf* psi)
+{
+    i_perf_server* ips = (i_perf_server*) new_object (sizeof(i_perf_server), 
+        ETCHTYPEB_EXESERVERBASE, get_dynamic_classid_unique(&CLASSID_EXESERVERBASE_PERF));
+
+    /* the server impl is destroyed via this base object. the virtual destructor we assign
+     * here will call the impl object's virtual destructor, which will directly call a 
+     * non-virtual destructor for the base object. 
+     */
+    ips->destroy = destroy_perf_server_via_base;
+
+    ips->thisx   = implobj; /* null passed thru from client main */
+
+    if (psi)
+        ips->iperf = psi;
+    else
+    {   ips->iperf = new_perf_service_interface();
+        ips->is_service_interface_owned = TRUE;
+    }
+     
+    ips->add     = ips->iperf->add;
+    ips->sum     = ips->iperf->sum;
+    ips->report  = ips->iperf->report;
+    ips->dist    = ips->iperf->dist;
+    ips->add2    = ips->iperf->add2;
+    ips->report2 = ips->iperf->report2;
+    ips->point   = ips->iperf->point;
+
+    ips->iobjsession = new_default_objsession_interface (ips);
+    ips->_session_control = ips->iobjsession->_session_control; 
+    ips->_session_notify  = ips->iobjsession->_session_notify; 
+    ips->_session_query   = ips->iobjsession->_session_query; 
+
+    ips->server_id = ++perf_server_id_farm;
+
+    return ips;
+}
+
+
+/**
+ * new_perf_remote_server_base()  
+ * constructor for server base when host is a remote server.
+ * the server base destructor in this case destroys only itself.   
+ * @param psi a perf service interface, if supplied, caller retains.
+ * may be null.
+ */
+i_perf_server* new_perf_remote_server_base (void* implobj, i_perf* psi)
+{
+    i_perf_server* ips = new_perf_server_base (implobj, psi);
+    ips->destroy = destroy_perf_server_base;
+    return ips;
+}
+
+
+/**
+ * destroy_perf_server_base()
+ * i_perf_server destructor.
+ */
+int destroy_perf_server_base (i_perf_server* ips)
+{
+    if (NULL == ips) return -1;
+    if (ips->refcount > 0 && --ips->refcount > 0) return -1;  
+
+    if (!is_etchobj_static_content(ips))
+    {    
+        if (ips->is_service_interface_owned)
+            ETCHOBJ_DESTROY(ips->iperf);
+
+        etch_free(ips->iobjsession);
+    }
+            
+    return destroy_objectex((objmask*)ips);
+}
+
+
+/**
+ * destroy_perf_server_via_base()
+ * destructor for perf_server_impl via i_perf_server.
+ */
+int destroy_perf_server_via_base (i_perf_server* ips)
+{
+    if (NULL == ips) return -1;
+    if (ips->refcount > 0 && --ips->refcount > 0) return -1;  
+
+    if (!is_etchobj_static_content(ips))
+    {    
+        /* serverimpl dtor will call base dtor (destroy_perf_server_base) */
+        objmask* serverimpl = (objmask*) ips->thisx;
+        ETCH_ASSERT(is_etch_serverimpl(serverimpl));
+        ETCHOBJ_DESTROY(serverimpl);
+    }
+
+    return 0;
+}
+

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server.h
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server.h?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server.h (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server.h Wed Apr 22 17:25:43 2009
@@ -0,0 +1,123 @@
+/* $Id$ 
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
+ * contributor license agreements. See the NOTICE file distributed with  
+ * this work for additional information regarding copyright ownership. 
+ * The ASF licenses this file to you under the Apache License, Version  
+ * 2.0 (the "License"); you may not use this file except in compliance  
+ * with the License. You may obtain a copy of the License at 
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License. 
+ */ 
+
+/*
+ * xmpl_perf_server.h
+ * perf service interface.
+ * combines java bindings's PerfServer and BasePerfServer
+ */
+
+#ifndef PERF_SERVER_H
+#define PERF_SERVER_H
+
+#include "xmpl_perf.h"
+#include "etch_sessionint.h"
+static int perf_server_id_farm;
+
+unsigned short CLASSID_EXESERVERBASE_PERF;
+
+typedef struct perf_server_impl perf_server_impl;
+
+/* these constants are here only for purposes of testing the throwing
+ * of remote etch exceptions by the perf  server implementation. they
+ * will not be part of generated code.
+ */
+#define FAKEBADDATA_INT32 ETCHTYPE_MIN_INT32
+#define FAKEBADDATA_INT64 ETCHTYPE_MIN_INT64
+#define FAKEBADDATA_STRING L"baddata"
+#define FAKEBADDATA_DATE  ((time_t) 0x1000)
+
+
+/**
+ * i_perf_server
+ * perf server base interface
+ */
+typedef struct i_perf_server
+{
+    unsigned int    hashkey;  
+    unsigned short  obj_type; 
+    unsigned short  class_id;
+    struct objmask* vtab;  
+    int  (*destroy)(void*);
+    void*(*clone)  (void*); 
+    obj_gethashkey  get_hashkey;
+    struct objmask* parent;
+    etchresult*     result;
+    unsigned int    refcount;
+    unsigned int    length;
+    unsigned char   is_null;
+    unsigned char   is_copy;
+    unsigned char   is_static;
+    unsigned char   reserved;
+
+    perf_server_impl* thisx;
+    i_perf* iperf;
+    int session_id;
+    unsigned char is_service_interface_owned;
+    unsigned char unused[3];
+
+    /* - - - - - - - - - - -
+     * objsession
+     * - - - - - - - - - - -
+     */
+    i_objsession* iobjsession;
+    etch_session_control _session_control;
+    etch_session_notify  _session_notify;
+    etch_session_query   _session_query;
+
+
+    /* - - - - - - - - - - -
+     * service virtuals
+     * - - - - - - - - - - -
+     */
+    perf_add      add;
+    perf_sum      sum;
+    perf_report   report;
+    perf_dist     dist;
+    perf_add2     add2;
+    perf_report2  report2;
+
+    perf_add      async_add;
+    perf_sum      async_sum;
+    perf_report   async_report;
+    perf_dist     async_dist;
+    perf_add2     async_add2;
+    perf_report2  async_report2;
+
+    /* - - - - - - - - - - -
+     * service data
+     * - - - - - - - - - - -
+     */
+    perf_point*   point;
+
+    /* - - - - - - - - - - -
+     * private instance data
+     * - - - - - - - - - - -
+     */
+    int server_id;
+
+} i_perf_server;
+
+
+i_perf_server* new_perf_server_base (void* implobj, i_perf*);
+i_perf_server* new_perf_remote_server_base (void* implobj, i_perf*);
+int destroy_perf_server_base (i_perf_server*);
+
+
+#endif /* PERF_SERVER_H */
+

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_impl.c
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_impl.c?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_impl.c (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_impl.c Wed Apr 22 17:25:43 2009
@@ -0,0 +1,333 @@
+/* $Id$ 
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
+ * contributor license agreements. See the NOTICE file distributed with  
+ * this work for additional information regarding copyright ownership. 
+ * The ASF licenses this file to you under the Apache License, Version  
+ * 2.0 (the "License"); you may not use this file except in compliance  
+ * with the License. You may obtain a copy of the License at 
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License. 
+ */ 
+
+/*
+ * xmpl_perf_server_impl.c
+ * your custom implementation of perf_server. 
+ * add your implementations of messages from the client here.   
+ * this code is generated in stub form, and manually augmented. 
+ */
+
+#include "apr_time.h" /* some apr must be included first */
+#include "xmpl_perf_server_impl.h"
+#include "etch_global.h"
+#include "etch_arrayval.h"
+#include "etch_binary_tdo.h"
+#include "etchexcp.h"
+#include "etch_url.h" 
+#include "etchlog.h" 
+
+#include <tchar.h>
+#include <stdio.h>
+#include <conio.h>
+char* ETCHSIMP = "SIMP";
+
+/* generated signatures */
+int destroy_perf_server_implex (perf_server_impl*);
+perf_server_impl* init_perf_server_impl (perf_remote_client*, etch_destructor);
+
+etch_int32* perf_impl_add    (void* perfserver, etch_int32*, etch_int32*);
+etch_int32* perf_impl_sum    (void* perfserver, void* array);
+void*       perf_impl_report (void* perfserver, etch_int32*, etch_string*);
+perf_point* perf_impl_dist   (void* thisx, perf_point*, perf_point*);
+etch_date*  perf_impl_add2   (void* thisx, etch_date*, etch_int64*); 
+void*       perf_impl_report2(void* thisx, etch_date*, etch_int32*, etch_string*);
+int         perf_objsession_notify (i_objsession*, etch_event*);
+
+
+/* - - - - - - - -    
+ * instantiation
+ * - - - - - - - -   
+ */
+
+/**
+ * new_perf_server_impl()
+ * perf_server_impl constructor.
+ * add your custom initialization and virtual method overrides here.
+ */
+perf_server_impl* new_perf_server_impl (perf_remote_client* client) 
+{
+    perf_server_impl* serv  /* allocate object and assign default virtuals */
+        = init_perf_server_impl (client, destroy_perf_server_implex); 
+    i_perf_server* iserv = serv->perf_server_base;
+
+    serv->class_id = get_dynamic_classid_unique(&CLASSID_PERFSERVERBASE_IMPL);
+
+    /* * *  add your custom construction/initialization here  * * */
+    serv->t0 = etch_system_nanotime();
+    serv->exampleobj = etch_malloc(100,0);
+    /* end custom construction/initialization */
+
+    /* * *  add your virtual method overrides here  * * */
+    /* todo avoid using and initializing two objects maybe don't put in impl */
+    serv->add     = iserv->add     = perf_impl_add;
+    serv->sum     = iserv->sum     = perf_impl_sum;;
+    serv->report  = iserv->report  = perf_impl_report;
+    serv->dist    = iserv->dist    = perf_impl_dist;
+    serv->add2    = iserv->add2    = perf_impl_add2;
+    serv->report2 = iserv->report2 = perf_impl_report2;
+    /* end virtual method overrides */
+
+    serv->_session_notify = serv->iobjsession->_session_notify = perf_objsession_notify;
+
+    return serv;
+}
+
+
+/**
+ * destroy_perf_server_implex()
+ * destructor for any user allocated memory.
+ * this code is invoked by the private perf_server_impl destructor,
+ * via perf_server.destroyex(). add code here to destroy any memory you  
+ * may have allocated for your custom perf_server implementation.
+ */
+int destroy_perf_server_implex (perf_server_impl* thisx)
+{
+    /* * *  add your custom destruction here  * * */
+    etch_free(thisx->exampleobj);
+    /* end custom destruction */
+
+    return 0;
+}
+
+
+/* - - - - - - - - - - - - - - - -  
+ * service method implementations
+ * - - - - - - - - - - - - - - - -  
+ */
+
+/**
+ * perf_impl_add()
+ * execution of perf.add()
+ * @param x an etch_int32 retained by the message value factory.
+ * @param y an etch_int32 retained by the message value factory.
+ * @return an etch_int32 whose value is the sum of x and y values.
+ */
+etch_int32* perf_impl_add (perf_server_impl* thisx, etch_int32* x, etch_int32* y)
+{
+    int is_argerr = 0;
+    etch_int32* resultobj = new_int32(0);
+    etchlog(ETCHSIMP, ETCHLOG_XDEBUG, "execute perf.add\n");
+    thisx->adds++;
+    ETCH_ASSERT(x && y); 
+    is_argerr = x->is_null || y->is_null;
+    if (x->value == FAKEBADDATA_INT32 || y->value == FAKEBADDATA_INT32) 
+        is_argerr = TRUE;  /* artificial constant for negative test */
+
+    if (is_argerr)  
+        etch_throw (resultobj, EXCPTYPE_ILLEGALARG, L"bad data", 0);
+    else
+        resultobj->value = x->value + y->value; 
+   
+    return resultobj;
+}
+
+
+/**
+ * perf_impl_sum()
+ * execution of perf.sum()
+ * @param a an etch_arrayvalue or etch_nativearray retained by the message's
+ * value factory.
+ * @return an etch_int32 whose value is the sum of the items in the array.
+ */
+etch_int32* perf_impl_sum (perf_server_impl* thisx, void* a)
+{
+    int is_argerr = 0;
+    etch_int32* resultobj = new_int32(0);
+    etchlog(ETCHSIMP, ETCHLOG_XDEBUG, "execute perf.sum\n");
+    thisx->sums++;
+    ETCH_ASSERT(a);
+
+    do
+    {   etch_arrayvalue* av = normalize_etch_array(a, 1);  
+        etch_iterator iterator;
+        if (is_argerr = (av == NULL || av->is_null)) break;
+       
+        arrayvalue_set_iterator(av, &iterator);
+
+        while(iterator.has_next(&iterator))
+        {
+            etch_int32* thisitem = (etch_int32*) iterator.current_value;
+            if (!is_etch_int32(thisitem) || thisitem->value == FAKEBADDATA_INT32)
+            {   is_argerr = TRUE;
+                break;
+            }
+
+            resultobj->value += thisitem->value;
+            iterator.next(&iterator);
+        }
+
+    } while(0);
+
+    if (is_argerr) etch_throw (resultobj, EXCPTYPE_ILLEGALARG, NULL, 0);
+
+    #if(0)
+    etchlog(ETCHSIMP, ETCHLOG_INFO, "perf_impl_sum test exception\n");
+    etch_throw (resultobj, EXCPTYPE_ILLEGALARG, L"test exception", ETCHEXCP_COPYTEXT);
+    #endif
+
+    return resultobj;
+}
+
+
+/**
+ * perf_impl_report()
+ * execution of perf.report()
+ * @param code an integer object retained by the message value factory.
+ * @param x an etch_string retained by the message value factory.
+ * @return null on success, an exception object on failure.
+ */
+void* perf_impl_report (perf_server_impl* thisx, etch_int32* code, etch_string* x)
+{
+    int is_argerr = 0;
+    void* resultobj = NULL;
+    etchlog(ETCHSIMP, ETCHLOG_XDEBUG, "execute perf.report\n");
+    thisx->reports++;
+    ETCH_ASSERT(code && x);
+    is_argerr = code->is_null || x->is_null;
+    /* artificial constants for negative tests */
+    if (code->value == FAKEBADDATA_INT32) is_argerr = TRUE;
+    if (0 == wcscmp(x->v.valw, FAKEBADDATA_STRING)) is_argerr = TRUE;   
+
+    if (is_argerr)
+        resultobj = new_etch_exception(EXCPTYPE_ILLEGALARG, NULL, 0);
+     
+    return resultobj;
+}
+
+
+/**
+ * perf_impl_dist()
+ * execution of perf.dist()
+ * @param p1 a perf_point retained by the message value factory.
+ * @param p2 a perf_point retained by the message value factory.
+ * @return a perf_point.
+ */
+perf_point* perf_impl_dist (perf_server_impl* thisx, perf_point* p1, perf_point* p2)
+{
+    int is_argerr = 0;
+    int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+    etchlog(ETCHSIMP, ETCHLOG_XDEBUG, "execute perf.dist\n");
+    thisx->dists++; 
+    ETCH_ASSERT(p1 && p2);
+    is_argerr = !is_perf_point(p1) || !is_perf_point(p2);
+    if (p1->x == FAKEBADDATA_INT32 || p1->y == FAKEBADDATA_INT32
+     || p2->x == FAKEBADDATA_INT32 || p2->y == FAKEBADDATA_INT32)
+        is_argerr = TRUE; /* artificial constant for negative tests */
+
+    if (is_argerr)
+        return (perf_point*) etch_throw (new_perf_point(0,0), 
+            EXCPTYPE_ILLEGALARG, NULL, 0);
+
+    x1 = p1->x; y1 = p1->y;  
+    x2 = p2->x; y2 = p2->y; 
+
+    return new_perf_point(x2 - x1, y2 - y1);
+}
+
+
+/**
+ * perf_impl_add2()
+ * execution of perf.add2()
+ * @param objdate an etch_date retained by the message value factory.
+ * @param objms an etch_int64 retained by the message value factory.
+ * @return an etch_date*.
+ */
+etch_date* perf_impl_add2 (perf_server_impl* thisx, etch_date* objdate, etch_int64* objms)
+{
+    int  is_argerr = 0;
+    etch_date* result_date = new_date();
+    etchlog(ETCHSIMP, ETCHLOG_XDEBUG, "execute perf.add2\n");
+    thisx->add2s++;
+    ETCH_ASSERT(objdate && objms);
+    is_argerr = objdate->is_null || objms->is_null;
+    if (objdate->value == FAKEBADDATA_DATE || objms->value == FAKEBADDATA_INT64)
+        is_argerr = TRUE; /* artificial constants for negative tests */
+
+    if (is_argerr) 
+        etch_throw (result_date, EXCPTYPE_ILLEGALARG, NULL, 0);
+    else
+        result_date->value = objdate->value + (objms->value / 1000);
+
+    return result_date;
+}
+
+
+/**
+ * perf_impl_report2()
+ * execution of perf.report2()
+ * @param ts an etch_date retained by the message value factory.    
+ * @param n an integer object retained by the message value factory.
+ * @param x an etch_string retained by the message value factory.
+ * @return null on success, an exception object on failure.
+ */
+void* perf_impl_report2 (perf_server_impl* thisx, etch_date* ts, etch_int32* n, etch_string* x)
+{
+    int   is_argerr = 0;
+    void* resultobj = NULL;
+    etchlog(ETCHSIMP, ETCHLOG_XDEBUG, "execute perf.report2\n");
+    thisx->report2s++;
+    ETCH_ASSERT(ts && n && x);
+    is_argerr = ts->is_null || n->is_null || x->is_null;
+    /* artificial constants for negative tests */
+    if (ts->value == FAKEBADDATA_DATE || n->value == FAKEBADDATA_INT32
+    || (0 == wcscmp(x->v.valw, FAKEBADDATA_STRING))) is_argerr = TRUE;   
+
+    if (is_argerr)
+        resultobj = new_etch_exception(EXCPTYPE_ILLEGALARG, NULL, 0);
+
+    return resultobj;
+}
+  
+
+/* - - - - - - - - - - - - - - - - - - -
+ * session interface method overrides
+ * - - - - - - - - - - - - - - - - - - -
+ */
+
+int perf_objsession_notify (i_objsession* isession, etch_event* evt)
+{
+    int result = -1, evtype = evt? evt->value: 0;
+    perf_server_impl* perfobj = (perf_server_impl*) isession->thisx;
+
+    if (ETCHEVT_SESSION_DOWN == evtype)  
+    {
+        const int total 
+            = perfobj->adds  + perfobj->sums  + perfobj->reports
+            + perfobj->dists + perfobj->add2s + perfobj->report2s;
+
+        int64 t0 = perfobj->t0, t1 = etch_system_nanotime();
+
+        double dtime = (t1 - t0) / (double) 1000000000;
+        double drate = total / dtime;
+
+        char* mask 
+            = "\nperf server %d down - adds %d sums %d reports %d dists %d " 
+              "add2s %d report2s %d total %d %d time %7.3f rate %7.3f\n";
+
+        printf(mask, perfobj->perf_server_base->server_id,
+               perfobj->adds,  perfobj->sums,  perfobj->reports,
+               perfobj->dists, perfobj->add2s, perfobj->report2s, 
+               total, dtime, drate);
+
+        result = 0;
+    }
+
+    ETCHOBJ_DESTROY(evt);
+    return result;
+}
\ No newline at end of file

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_impl.h
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_impl.h?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_impl.h (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_impl.h Wed Apr 22 17:25:43 2009
@@ -0,0 +1,92 @@
+/*
+ * xmpl_perf_server_impl.h 
+ */
+
+#ifndef PERF_SERVER_IMPL_H
+#define PERF_SERVER_IMPL_H
+
+#include "xmpl_perf_server.h"
+#include "etch_transport.h"
+
+unsigned short CLASSID_PERFSERVERBASE_IMPL;
+
+typedef struct perf_remote_client perf_remote_client;
+
+/**
+ * perf_server_impl
+ * your custom implementation of perf_base_server. add methods here 
+ * to provide implementations of messages from the client, if any.
+ */
+typedef struct perf_server_impl
+{
+    unsigned int    hashkey;  
+    unsigned short  obj_type; 
+    unsigned short  class_id;
+    struct objmask* vtab;  
+    int  (*destroy)(void*);
+    void*(*clone)  (void*); 
+    obj_gethashkey  get_hashkey;
+    struct objmask* parent;
+    etchresult*     result;
+    unsigned int    refcount;
+    unsigned int    length;
+    unsigned char   is_null;
+    unsigned char   is_copy;
+    unsigned char   is_static;
+    unsigned char   reserved;
+
+    i_perf_server* perf_server_base;  /* owned */
+    i_perf*        iperf;         /* not owned */
+    perf_remote_client* client;   /* not owned */
+
+    int (*destroyex) (void*);  /* user memory destructor */
+
+    /* - - - - - - - - - - - -
+     * objsession
+     * - - - - - - - - - - - -
+     */
+    i_objsession* iobjsession;  /* owned by base */
+    /* note that iobjsession->thisx is set to this perf_server_impl* */
+    etch_session_control _session_control;
+    etch_session_notify  _session_notify;
+    etch_session_query   _session_query;
+
+    /* - - - - - - - - - - - -
+     * base service virtuals
+     * - - - - - - - - - - - -
+     */
+    perf_add      add;
+    perf_sum      sum;
+    perf_report   report;
+    perf_dist     dist;
+    perf_add2     add2;
+    perf_report2  report2;
+
+
+    /* - - - - - - - - - - - -
+     * base service data
+     * - - - - - - - - - - - -
+     */
+    perf_point* point;   /* owned by base */
+
+
+    /* - - - - - - - - - - - - -
+     * custom instance data 
+     * - - - - - - - - - - - - -
+     */
+
+    /* * *  add custom instance data here  * * */
+    int adds, sums, reports, dists, add2s, report2s; 
+    char* exampleobj;
+    int64 t0;
+
+} perf_server_impl;
+
+
+
+/* constructor */
+perf_server_impl* new_perf_server_impl (perf_remote_client*);
+
+
+#endif /* PERF_SERVER_IMPL_H */
+

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_implx.c
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_implx.c?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_implx.c (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_implx.c Wed Apr 22 17:25:43 2009
@@ -0,0 +1,102 @@
+/* $Id$ 
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
+ * contributor license agreements. See the NOTICE file distributed with  
+ * this work for additional information regarding copyright ownership. 
+ * The ASF licenses this file to you under the Apache License, Version  
+ * 2.0 (the "License"); you may not use this file except in compliance  
+ * with the License. You may obtain a copy of the License at 
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License. 
+ */ 
+
+/*
+ * xmpl_perf_server_implx.c 
+ * perf_server_impl functions which would ordinarily not be subject to edit.
+ */
+
+#include "apr_time.h" /* some apr must be included first */
+#include "xmpl_perf_server_impl.h"
+#include "etch_global.h"
+#include "etch_url.h"  
+
+#include <tchar.h>
+#include <stdio.h>
+#include <conio.h>
+int destroy_perf_server_impl (perf_server_impl*);
+
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - -   
+ * server_impl private construction / destruction 
+ * - - - - - - - - - - - - - - - - - - - - - - - -    
+ */
+
+/**
+ * init_perf_server_impl()   
+ * called by perf_server_impl constructor to instantiate server implementation 
+ * object and initialize with default virtuals.
+ * @param client the remote client, not owned.
+ * @param usermem_dtor destructor for any custom memory allocations.
+ */
+perf_server_impl* init_perf_server_impl (perf_remote_client* client, 
+    etch_destructor usermem_dtor)
+{
+    perf_server_impl* ps = (perf_server_impl*) new_object (sizeof(perf_server_impl), 
+        ETCHTYPEB_EXESERVERIMPL, CLASSID_EXESERVERBASE_IMPL);  
+
+    ps->client  = client;  /* not owned */
+    ps->destroy = destroy_perf_server_impl;  /* private destructor */
+    ps->destroyex = usermem_dtor;  /* user memory destructor */
+
+    /* instantiate base and copy virtuals to this object */
+    ps->perf_server_base = new_perf_server_base (ps, NULL);  /* owned */
+    ps->iperf   = ps->perf_server_base->iperf;
+    ps->add     = ps->perf_server_base->add;
+    ps->sum     = ps->perf_server_base->sum;
+    ps->report  = ps->perf_server_base->report;
+    ps->dist    = ps->perf_server_base->dist;
+    ps->add2    = ps->perf_server_base->add2;
+    ps->report2 = ps->perf_server_base->report2;
+    ps->point   = ps->perf_server_base->point;
+
+    ps->iobjsession = ps->perf_server_base->iobjsession;
+    ps->iobjsession->thisx = ps;  /* set implementor reference */
+    ps->_session_control = ps->perf_server_base->_session_control;
+    ps->_session_notify  = ps->perf_server_base->_session_notify;
+    ps->_session_query   = ps->perf_server_base->_session_query;
+
+    return ps;
+}
+
+
+/**
+ * destroy_perf_server_impl()
+ * perf_server_impl private destructor.
+ * calls back to user destructor to effect cleanup of any perf_server_impl 
+ * memory which may have been allocated in custom code added by user.
+ */
+int destroy_perf_server_impl (perf_server_impl* ps)
+{
+    if (NULL == ps) return -1;
+    if (ps->refcount > 0 && --ps->refcount > 0) return -1;  
+
+    if (!is_etchobj_static_content(ps))
+    {    
+        if (ps->destroyex)     /* call back to user memory destructor */
+            ps->destroyex(ps);
+
+        if (ps->perf_server_base) /* destroy iobjession, service data */
+            /* must call dtor directly since virtual dtor is destroy via base */
+            destroy_perf_server_base (ps->perf_server_base);
+            //ps->perf_server_base->destroy(ps->perf_server_base);
+    }
+            
+    return destroy_objectex((objmask*)ps);
+}

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_stub.c
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_stub.c?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_stub.c (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_stub.c Wed Apr 22 17:25:43 2009
@@ -0,0 +1,370 @@
+/* $Id$ 
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
+ * contributor license agreements. See the NOTICE file distributed with  
+ * this work for additional information regarding copyright ownership. 
+ * The ASF licenses this file to you under the Apache License, Version  
+ * 2.0 (the "License"); you may not use this file except in compliance  
+ * with the License. You may obtain a copy of the License at 
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License. 
+ */ 
+
+/*
+ * xmpl_perf_server_stub.c 
+ */
+
+#include "apr_time.h" /* some apr must be included first */
+#include "xmpl_perf_server_stub.h"
+#include "xmpl_perf_valufact.h"
+#include "xmpl_perf_server.h"
+#include "etch_global.h"
+#include "etchexcp.h"
+#include "etch_url.h"  
+#include "etchlog.h"
+
+#include <tchar.h>
+#include <stdio.h>
+#include <conio.h>
+
+char* ETCHSTBI = "STBI";
+int destroy_my_server_stub (perf_server_stub*);
+
+
+/* - - - - - - - - - - -
+ * stub helper methods 
+ * - - - - - - - - - - -
+ */
+
+/* these are the possibly threaded server side implementations of calls to the
+ * service method logic in xxxx_server_impl. there is one such helper for each
+ * server-directed method in the service. each assembles and validates method
+ * parameters, invokes a call to the service logic, and transmits a result
+ * message if indicated. each conforms to the opaque_stubhelper signature:
+ * int stubhelper (void* stub, void* dsvc, void* obj, void* sender, void* msg); 
+ * @param stub the invoking stub object 
+ * @param dsvc delivery service - caller retains.
+ * @param server the service methods user logic, caller retains.
+ * @param whofrom sender, caller relinquishes.
+ * @param msg - the message, caller relinquishes. 
+ * @return 0 success, -1 failure of the message_put or send. success means that  
+ * the mechanism was successful, not necessarily that the service method logic
+ * was successful. when the service method logic fails, the result object will
+ * wrap an exception.
+ *
+ * NOTE CAREFULLY: at this writing, each stub helper method asserts its expected
+ * parameters (halts execution on null), and otherwise always calls the implemented 
+ * service method, which subsequently destroys whofrom and msg regardless of result. 
+ * if this were changed to instead return some error indicator from the stub helper
+ * method on detection of a null parameter, the stub helper method would need to 
+ * first destroy the whofrom and msg parameters to fulfill the stub helper method
+ * contract. 
+ */
+
+/**
+ * perfstub_run_add
+ */
+int perfstub_run_add (etch_stub* stub, i_delivery_service* dsvc, 
+    i_perf_server* server, etch_who* whofrom, etch_message* msg)
+{
+    perf_value_factory_impl* pvi = NULL;
+    perf_value_factory* pvf = NULL;
+    perf_server_impl* impl = NULL;
+
+    /* objects specific to perf.add() */
+    etch_field* key_x = NULL;
+    etch_int32* val_x = NULL;
+    etch_field* key_y = NULL;
+    etch_int32* val_y = NULL;
+    etch_int32* resultobj = NULL;
+
+    etchstub_validate_args (stub, dsvc, msg, server, &pvf, &pvi, &impl);     
+
+    key_x = pvi->statics._mf_x;
+    key_y = pvi->statics._mf_y;
+    ETCH_ASSERT(key_x && key_y);  
+
+    /* nullarg asserts are initial tests only: server impl   
+     * should generate exceptions on nullargs in the real world */
+    val_x = (etch_int32*) message_get (msg, key_x);
+    val_y = (etch_int32*) message_get (msg, key_y); 
+    ETCH_ASSERT(val_x && val_y); 
+
+    /* execute the service method */
+    resultobj = server->add (impl, val_x, val_y);
+
+    /* transmit reply back to sender */
+    return etchstub_send_reply (stub, dsvc, whofrom, msg, (void*) resultobj);
+}
+
+
+/**
+ * perfstub_run_sum
+ */
+int perfstub_run_sum (etch_stub* stub, i_delivery_service* dsvc, 
+    i_perf_server* server, etch_who* whofrom, etch_message* msg)
+{
+    perf_value_factory_impl* pvi = NULL;
+    perf_value_factory* pvf = NULL;
+    perf_server_impl* impl = NULL;
+
+    /* objects specific to perf.sum() */
+    etch_field* key_a = NULL;
+    etch_arraytype* val_a = NULL;
+    etch_int32* resultobj = NULL;
+
+    etchstub_validate_args (stub, dsvc, msg, server, &pvf, &pvi, &impl);     
+
+    key_a = pvi->statics._mf_values;
+    ETCH_ASSERT(key_a);  
+
+    /* nullarg asserts are initial tests only: server impl   
+     * should generate exceptions on nullargs in the real world */
+    val_a = (etch_arraytype*) message_get (msg, key_a);
+    ETCH_ASSERT(val_a); 
+
+    /* execute the service method */
+    resultobj = server->sum (impl, val_a);
+    ETCH_ASSERT(resultobj); 
+
+    /* transmit reply back to sender */
+    return etchstub_send_reply (stub, dsvc, whofrom, msg, (void*) resultobj);
+}
+
+
+/**
+ * perfstub_run_report
+ */
+int perfstub_run_report (etch_stub* stub, i_delivery_service* dsvc, 
+    i_perf_server* server, etch_who* whofrom, etch_message* msg)
+{
+    perf_value_factory_impl* pvi = NULL;
+    perf_value_factory* pvf = NULL;
+    perf_server_impl* impl = NULL;
+    int  result = 0;
+
+    /* objects specific to perf.report() */
+    etch_field* key_code = NULL;
+    etch_int32* val_code = NULL;
+    etch_field*  key_msg = NULL;
+    etch_string* val_msg = NULL;
+    etch_exception* excp = NULL;
+
+    etchstub_validate_args (stub, dsvc, msg, server, &pvf, &pvi, &impl);     
+
+    key_code = pvi->statics._mf_code;
+    key_msg  = builtins._mf_msg;
+    ETCH_ASSERT(key_code && key_msg);  
+
+    /* nullarg asserts are initial tests only: the server implementation   
+     * should generate exceptions on null args in the real world */
+    val_code = (etch_int32*)  message_get (msg, key_code);
+    val_msg  = (etch_string*) message_get (msg, key_msg);
+    ETCH_ASSERT(val_code && val_msg); 
+
+    /* execute the service method. for oneway messages such as this one,
+     * a non-null return value will always be an exception object. */
+    excp = server->report (impl, val_code, val_msg);
+    
+    if (is_etch_exception(excp)) /* transmit exception back to sender */
+        result = etchstub_send_reply (stub, dsvc, whofrom, msg, (void*) excp);
+
+    return result;
+}
+
+
+/**
+ * perfstub_run_dist
+ */
+int perfstub_run_dist (etch_stub* stub, i_delivery_service* dsvc, 
+    i_perf_server* server, etch_who* whofrom, etch_message* msg)
+{
+    perf_value_factory_impl* pvi = NULL;
+    perf_value_factory* pvf = NULL;
+    perf_server_impl* impl = NULL;
+
+    /* objects specific to perf.dist() */
+    etch_field* key_a = NULL;
+    perf_point* val_a = NULL;
+    etch_field* key_b = NULL;
+    perf_point* val_b = NULL;
+    perf_point* resultobj = NULL;
+
+    etchstub_validate_args (stub, dsvc, msg, server, &pvf, &pvi, &impl);     
+
+    key_a = pvi->statics._mf_a;
+    key_b = pvi->statics._mf_b;
+    ETCH_ASSERT(key_a && key_b);  
+
+    /* nullarg asserts are initial tests only: server impl   
+     * should generate exceptions on nullargs in the real world */
+    val_a = (perf_point*) message_get (msg, key_a);
+    val_b = (perf_point*) message_get (msg, key_b);
+    ETCH_ASSERT(val_a && val_b); 
+
+    /* execute the service method */
+    resultobj = server->dist (impl, val_a, val_b);
+    ETCH_ASSERT(resultobj);   
+    
+    /* transmit reply back to sender */
+    return etchstub_send_reply (stub, dsvc, whofrom, msg, (void*) resultobj);
+}
+
+
+/**
+ * perfstub_run_add2
+ */
+int perfstub_run_add2 (etch_stub* stub, i_delivery_service* dsvc, 
+    i_perf_server* server, etch_who* whofrom, etch_message* msg)
+{
+    perf_value_factory_impl* pvi = NULL;
+    perf_value_factory* pvf = NULL;
+    perf_server_impl* impl = NULL;
+
+    /* objects specific to perf.add2() */
+    etch_field* key_date = NULL;
+    etch_date*  val_date = NULL;
+    etch_field* key_ms = NULL;
+    etch_int64* val_ms = NULL;
+    etch_date*  resultobj = NULL;
+
+    etchstub_validate_args (stub, dsvc, msg, server, &pvf, &pvi, &impl);     
+
+    key_date = pvi->statics._mf_ts;
+    key_ms   = pvi->statics._mf_ms;
+    ETCH_ASSERT(key_date && key_ms);  
+
+    /* nullarg asserts are initial tests only: server impl   
+     * should generate exceptions on nullargs in the real world */
+    val_date = (etch_date*)  message_get (msg, key_date);
+    val_ms   = (etch_int64*) message_get (msg, key_ms);
+    ETCH_ASSERT(val_date && val_ms); 
+
+    /* execute the service method */
+    resultobj = server->add2 (impl, val_date, val_ms);
+    ETCH_ASSERT(resultobj);   
+    
+    /* transmit reply back to sender */
+    return etchstub_send_reply (stub, dsvc, whofrom, msg, (void*) resultobj);
+}
+
+
+/**
+ * perfstub_run_report2
+ */
+int perfstub_run_report2 (etch_stub* stub, i_delivery_service* dsvc, 
+    i_perf_server* server, etch_who* whofrom, etch_message* msg)
+{
+    perf_value_factory_impl* pvi = NULL;
+    perf_value_factory* pvf = NULL;
+    perf_server_impl* impl = NULL;
+    int  result = 0;
+
+    /* objects specific to perf.report2() */
+    etch_field* key_date = NULL;
+    etch_date*  val_date = NULL;
+    etch_field* key_code = NULL;
+    etch_int32* val_code = NULL;
+    etch_field*  key_msg = NULL;
+    etch_string* val_msg = NULL;
+    etch_exception* excp = NULL;
+
+    etchstub_validate_args (stub, dsvc, msg, server, &pvf, &pvi, &impl);     
+
+    key_date = pvi->statics._mf_ts;
+    key_code = pvi->statics._mf_code;
+    key_msg  = builtins._mf_msg;
+    ETCH_ASSERT(key_date && key_code && key_msg);  
+
+    /* nullarg asserts are initial tests only: server impl   
+     * should generate exceptions on nullargs in the real world */
+    val_date = (etch_date*)   message_get (msg, key_date);
+    val_code = (etch_int32*)  message_get (msg, key_code);
+    val_msg  = (etch_string*) message_get (msg, key_msg);
+    ETCH_ASSERT(val_date && val_code && val_msg); 
+
+    /* execute the service method. for oneway messages such as this one,
+     * a non-null return value will always be an exception object. */
+    excp = server->report2 (impl, val_date, val_code, val_msg);
+    
+    if (is_etch_exception(excp)) /* transmit exception back to sender */
+        result = etchstub_send_reply (stub, dsvc, whofrom, msg, (void*) excp);
+
+    return result;
+}
+
+
+/* - - - - - - - - - 
+ * constructors 
+ * - - - - - - - - - 
+ */
+
+/**
+ * new_perf_server_stub()
+ * @param p serv factory parameter bundle, caller retains. 
+ *
+ * this constructor is called on the server via callback from the listener 
+ * socket accept handler <transportfactory>_session_accepted, via the new_server 
+ * function pointer to perf_helper.new_helper_accepted_server().
+ * java binding passes this constructor the delivery service, however we pass the
+ * etch_server_factory parameter bundle, (i_sessionlistener.server_params),
+ * i_sessionlistener being the set session interface of etch_tcp_server. 
+ */
+perf_server_stub* new_perf_server_stub (etch_server_factory* p, etch_session* session)
+{
+    i_delivery_service* ids = session->ds;
+    perf_value_factory* pvf = (perf_value_factory*) p->in_valufact;
+    perf_value_factory_impl* pvi = (perf_value_factory_impl*) pvf->impl;
+    etch_threadpool *qp = p->qpool, *fp = p->fpool;
+
+    perf_server_stub* mystub = new_serverstub_init (session->server,  
+        sizeof(perf_server_stub), destroy_my_server_stub, ids, qp, fp, p);
+
+    mystub->class_id   = get_dynamic_classid_unique(&CLASSID_STUBSERVER_PERF);
+    mystub->session_id = session->session_id;  
+
+    /* initialize service-specific methods and data here. this facility may
+     * likely prove unecessary, as this is generated code, in which case we 
+     * can remove any associated comments from code and headers. */
+    mystub->my_example_obj = etch_malloc(128, 0); /* example custom alloc */
+
+    /* set stub "helper" methods (run() procedures for each message type) */
+    etchtype_set_type_stubhelper(pvi->statics._mt_etch_xmpl_perfserver_add, 
+        perfstub_run_add);
+    etchtype_set_type_stubhelper(pvi->statics._mt_etch_xmpl_perfserver_sum, 
+        perfstub_run_sum);
+    etchtype_set_type_stubhelper(pvi->statics._mt_etch_xmpl_perfserver_report, 
+        perfstub_run_report);
+    etchtype_set_type_stubhelper(pvi->statics._mt_etch_xmpl_perfserver_dist, 
+        perfstub_run_dist);
+    etchtype_set_type_stubhelper(pvi->statics._mt_etch_xmpl_perfserver_add2, 
+        perfstub_run_add2);
+    etchtype_set_type_stubhelper(pvi->statics._mt_etch_xmpl_perfserver_report2, 
+        perfstub_run_report2);
+
+    return mystub;
+}
+
+
+/**
+ * destroy_my_server_stub()
+ * perf_server_stub user-allocated memory destructor.
+ * called back from private object destructor destroy_stub_object().
+ * if you explicitly allocate memory in the server stub object, destroy it here.
+ */
+int destroy_my_server_stub (perf_server_stub* mystub)
+{
+    /* free custom memory allocations here. this facility may
+     * likely prove unecessary, as this is generated code, in which case we 
+     * can remove any associated comments from code and headers. */
+    etch_free(mystub->my_example_obj); /* free example alloc */
+
+    return 0;
+}
+

Added: incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_stub.h
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_stub.h?rev=767594&view=auto
==============================================================================
--- incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_stub.h (added)
+++ incubator/etch/trunk/binding-c/runtime/c/src/xamples/perf/xmpl_perf_server_stub.h Wed Apr 22 17:25:43 2009
@@ -0,0 +1,77 @@
+/* $Id$ 
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
+ * contributor license agreements. See the NOTICE file distributed with  
+ * this work for additional information regarding copyright ownership. 
+ * The ASF licenses this file to you under the Apache License, Version  
+ * 2.0 (the "License"); you may not use this file except in compliance  
+ * with the License. You may obtain a copy of the License at 
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and 
+ * limitations under the License. 
+ */ 
+
+/*
+ * xmpl_perf_server_stub.h
+ * perf server stub
+ */
+
+#ifndef PERF_SERVER_STUB_H
+#define PERF_SERVER_STUB_H
+
+#include "etch_stub.h"
+unsigned short CLASSID_STUBSERVER_PERF;
+
+
+/**
+ * perf_server_stub
+ */
+typedef struct perf_server_stub
+{
+    unsigned int    hashkey;  
+    unsigned short  obj_type; 
+    unsigned short  class_id;
+    struct objmask* vtab;  
+    int  (*destroy)(void*);
+    void*(*clone)  (void*); 
+    obj_gethashkey  get_hashkey;
+    struct objmask* parent;
+    etchresult*     result;
+    unsigned int    refcount;
+    unsigned int    length;
+    unsigned char   is_null;
+    unsigned char   is_copy;
+    unsigned char   is_static;
+    unsigned char   reserved;
+
+    etch_stub* stub_base;
+    int  session_id;           /* client session to which stub belongs */
+    int (*destroyex) (void*);  /* user memory destructor */
+
+    /* - - - - - - - - - - - - - - - - -
+     * server_directed service virtuals
+     * - - - - - - - - - - - - - - - - -
+     */  
+
+     /* no server-directed methods */
+
+    /* - - - - - - - - - - - - - - - - -
+     * service-specific allocations
+     * - - - - - - - - - - - - - - - - -
+     */   
+    char* my_example_obj;  
+
+} perf_server_stub;
+
+
+perf_server_stub* new_perf_server_stub (etch_server_factory*, etch_session*);
+int destroy_perf_server_stub (perf_server_stub*);
+
+
+#endif /* PERF_SERVER_STUB_H */
+