BPEL Threading Model

I have three BPEL Processes: BPEL1, BPEL2 and BPEL3 invoking each other in a synchronous fashion as shown below:
Synchronous flow - BPEL1 -> BPEL2 -> BPEL3
I have a java web service which sends in the request to the BPEL1. I would like to increase the no of threads to handle more requests from the Java web service. I looked up four parameters that can be tuned:
Dispatcher Invoke Threads
Dispatcher Engine Threads
Dispatcher System Threads
Dispatcher Maximum Request Depth
As per my understanding Dispatcher Invoke Threads comes into the picture when a synchronous transaction is involved. The question I have is:
Is the value of 20 per instance of BPEL Process or per synchronous transaction? With the above flow stated, BPEL1 invoking BPEL2, BPEL2 invoking BPEL3 and response flow from BPEL3 to BPEL2 and BPEL2 to BPEL1, all being synchronous calls, is this parameter for every instance of BPEL1 alone (per synchronous transaction) or per BPEL instance of BPEL1,BPEL2 and BPEL3?*

No, "Dispatcher Invoke Threads" come into play with async (oneway / possible callbacks). This setting controls the threadpool size to create new process instances, after the originator thread saved the instance data and returned.
Engine threads handle callbacks and expirations
System threads are cleanup threads

Similar Messages

  • Alternative Threading Model in Solaris 8?

    I haven't been able to get to any Solaris 8 docs yet, but I've been hearing about his alternative threading model available in Solaris 8. Can someone explain it to me?

    I know this question was posted a while ago, but this info may be of help.
    As well as improved real-time support for threads, Solaris 8 has an extra set of thread libraries under /usr/lib/lwp.
    They are designed to be direct replacements for the standard libraries; you can pick them up by linking against them or using LD_LIBRARY_PATH.
    This new one-level libthread is a library that implements all of the POSIX and Solaris threads interfaces using a one-level threading model, where threads are one-to-one with lightweight processes (LWPs), rather than the two-level model that is used in the standard libthread implementation, where user-level threads are multiplexed over possibly fewer LWPs.
    It has been found in tests that some applications perform much better with the new library. However, more kernel resources are consumed.
    Hope that helps.
    Ralph
    SUN DTS

  • Xsql servlet threading model?

    does anybody know the threading model supporting by the xsql servlet? from my testing, it appears that it only supports single threaded.
    environment: nt 4.0, svcpack 5/iis/servlet exec 2.2/jdk 1.1.8/xsql servlet 0.9.6
    any help/info appreciated.
    thanks
    michael lasmanis

    steve,
    here are the java vm settings from servlet exec. all the other settings are in line with the install instructions.
    VM Settings
    Java VM: 1.1.8 from Sun Microsystems Inc.
    JITC: symcjit
    Host: Windows NT 4.0 on x86
    Native Stack Size: 128K Bytes
    Java Stack Size: 400K Bytes
    Minimum Heap Size: 1024K Bytes
    Maximum Heap Size: 524288K Bytes
    Verbose GC: Disabled
    Verbose: Disabled
    JITC: Enabled
    Class GC: Enabled
    Async GC: Enabled
    Verify: Remote
    Java VM: Sun Classic
    null

  • Single Threaded Model JSP- Servlet

    Servelts can be set to have thread safe access (Single thread model). However, when a JSP is converted in to a servlet, is the servlet tagged as to use the single thread model?

    As of JSP specification 1.2 the default value for the "isThreadSafe" attribute of the page directive is true indicating that the container can direct multiple requests to the page simultaneously. If this value is set to false then the requests will be sent one at a time.
    Good Luck!
    Eshwar Rao
    Developer Technical Support
    Sun microsystems inc
    http://www.sun.com/developers/support

  • BPEL Process Modeler

    According to the documentation I should see "BPEL Process Manager Server" under the connections in JDev (version 10.1.3.3). I have installed the SOA suite and Business Process Manager.
    I do not see this - I am sure I have missed something. Thanks
    To add..the steps after BPM install say:
    "Install JDeveloper
    Please follow the install instructions available on the download page to install the Studio Edition of JDeveloper. This version of JDeveloper already includes the BPEL and ESB Designer plugins."
    I see the plugin/extension:
    BPEL Process Modeler     oracle.bpm.modeler     10.1.3.1.0.070615.0525     Loaded
    I just can't seem to use it.
    Message was edited by:
    smay

    You might want to ask this on the SOA Suite forum: SOA Suite

  • Native pthread mutex on 1:1 threading model

    Hi,
    I wanted to verify with the experts that it is safe to use a native mutex in JNI instead of
    MonitorEnter/MonitorExit on all JREs that map a java thread to a native thread in a
    1:1 fashion. Why do this? Because MonitorEnter/Exit pair takes 500 nanos which
    is way to slow for my JNI component. Of course, on threading models that
    are not 1:1 I am definitely not safe(?).
    By the way, does anyone know if the SUN hotspot for windows is a 1:1 threading model.
    I know that it is for Linux.
    Andy

    i know that it's old but some other ppl can found it.
    actually i'm using a pthread_mutex_lock on linux/unix and WaitForSingleObject on windows. see, i don't create threads inside the jni glue, but i create mutexes.
    it seems to work well, but for some unknow reason it leads to deadlocks on certain unices.
    right now i'm going to change my implementations for MonitorEnter/Exit and GetPrimitiveArrayCritical.

  • Threading model: Linux, MacOSX, Win32

    Hi,
    I've been searching these forums for topics regarding Java threading models for the three operating systems for which we build Java applications: Linux, MacOSX and Windows. So far, I've only got a clear picture on the Win32 environment. It uses native threads, which I'm told is best for performance.
    My question is: what threading models do the virtual machines for Linux and MacOSX support these days? Are they working with socalled "green threads" or do they use the more powerful native threads as well? I can't seem to find any recent posts with information on this subject.
    Thanks in advance

    Here is an article that you might find interesting:
    Programming Java threads in the real world
    http://www.javaworld.com/javaworld/jw-09-1998/jw-09-threads.html
    Jesper

  • Struts Action threading model bottleneck

    Hi,
    Struts Action classes are only instantiated once. Then the controller servlet routes all perform/execute calls through the single instantiated Action class. Does this create a performance bottleneck? Any insights would be helpful.
    Thanks

    It's more performant, since it doesn't need to create new objects for each request. You just need to write your code in a thread-safe manner (watch the instance variable!).
    Cheers

  • Transient and Durable Process

    Can anyone explain me what is transient and durable bpel processes are?
    Regards
    Senthil R

    Senthil, as far as my knowledge no such information is stored in database.
    Sundar, what is your goal? We normally work with our simple sync and async terms only. Transient/Durable or one/two way invocation are the ways to categorize the BPEL Process and its activities to improve the performance. I request you to study BPEL Threading Model. You can refer the OTN page http://download.oracle.com/docs/cd/B31017_01/core.1013/b28942/tuning_bpel.htm and get more information.
    As you will be aware, typical sync process is a single web service call where the process is initiated, executes the logic and sends the response back to caller. Till the response arrives the caller would be waiting for that (and timeout calculations would be going on). Synchronous are typical Transient process if the criterion in the above forum post is matched. But suppose, in any invoke activity the idempotent property is set to false (default is true), the BPEL process will dehydrate the instance soon after that invoke activity and this process is durable process. Hope this explains.
    Ahmed is right, he writes that durable processes are long-living and initiated through a one-way invocation. There might be separate call back for such processes to send the response back to the caller process. Typical Async example.

  • XML over HTTP using BPEL (not using SOAP)... is this possible?

    Hi there.
    We're trying to expose a BPEL process which will be exclusively triggered from a HTTP POST. The Client Partner Link in the BPEL process models Oracle's Transparent PunchOut standard. This standard is strict XML-over-HTTP, SOAP is not involved.
    However, I am getting issues when I POST the XML to BPEL. It is telling me that it requires a SOAPAction in the header. Again, the design dictates that this is raw XML over HTTP, so we are not to use any SOAP specific header values nor any kind of SOAP wrapper.
    I deployed the sample 'HTTPPostService' process which was delivered with BPEL. I am seeing the same error when I try to POST XML to this process as well. I get a response (in a SOAP wrapper) saying that it wants a SOAPAction in the header. The WSDL used to create this sample process clearly does not bind to SOAP, (there are no mentions of the SOAPAction in the operation, etc) so I do not understand.
    So, my question is: Is is possible to POST raw XML to a BPEL process? Or does BPEL require all processes to follow the SOAP 'protocol' ?
    Thanks for any help.
    Message was edited by:
    [email protected]

    I am also trying to do the same stuff. If i deploy the sample application HttpGetService, will i be able to send the request from browser the way we send typical http get request?
    here is the url which i want to use to invoke Http get BPEL
    http://cybage1:9700/httpbinding/default/HTTPGetService?ssn=10&id=20
    but i am getting following exception
    500 Internal Server Error
    java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
         at java.util.ArrayList.RangeCheck(ArrayList.java:507)
         at java.util.ArrayList.get(ArrayList.java:324)
         at com.collaxa.cube.ws.http.HttpBindingServlet.call(HttpBindingServlet.java:113)
         at com.collaxa.cube.ws.http.HttpBindingServlet.doGet(HttpBindingServlet.java:97)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
         at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.0)].server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:810)
         at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.0)].server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:322)
         at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.0)].server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:798)
         at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.0)].server.http.HttpRequestHandler.run(HttpRequestHandler.java:278)
         at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.0)].server.http.HttpRequestHandler.run(HttpRequestHandler.java:120)
         at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.0)].util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:186)
         at java.lang.Thread.run(Thread.java:534)

  • Problem with threads hanging

    We have a problem where our application stops responding after a few days of usage. Things will for fine for a day or two, and then pretty quickly threads will start getting hung up, usually in places where they are allocating memory
    We are running WebLogic 8.1 SP2 on Sun JDK 1.4.2_04 on Solaris 8 using the alternate threading model and the -server hotspot vm. We are running pretty much the same code that we had no problems with under WebLogic 6.1 SP4 and Sun JDK 1.3.1.
    A thread dump usually shows that some or all of our execute threads are in the state "waiting for monitor entry" even though they are not currently waiting on any java locks. Here is a sample thread from the thread dump (we have ~120 threads so I don't want to post the full dump).
    =============================================================================================
    "ExecuteThread: '8' for queue: 'itgCrmWarExecutionQueue'" daemon prio=5 tid=0x005941d0 nid=0x2c waiting for monitor entry [c807f000..c807fc28]
    at java.lang.String.substring(String.java:1446)
    at java.lang.String.substring(String.java:1411)
    at weblogic.servlet.internal.ServletRequestImpl.getRelativeUri(ServletRequestImpl.java:1872)
    at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3492)
    at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2585)
    at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:197)
    at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:170)
    =============================================================================================
    String.java line 1446 for this jdk allocates a new String object, and all the other threads in this state also are creating new objects or arrays, etc.
    We've done a pstack on this process when it's in this state, and the threads that are in the "waiting for monitor entry" that look like they're allocating memory are all waiting on the same lwp_mutex_lock with some allocation method that's calling into the native TwoGenerationCollectorPolicy.mem_allocate_work (see pstack output below for the same thread as in the thread dump above)
    =============================================================================================
    ----------------- lwp# 44 / thread# 44 --------------------
    ff31f364 lwp_mutex_lock (e3d70)
    fee92384 __1cNObjectMonitorGenter26MpnGThread__v_ (5000, 525c, 5000, 50dc, 4800, 4af0) + 2d8
    fee324d4 __1cSObjectSynchronizerKfast_enter6FnGHandle_pnJBasicLock_pnGThread__v_ (c807f65c, c807f7d4, 5941d0, 0, 35d654, fee328ec) + 68
    fee32954 __1cQinstanceRefKlassZacquire_pending_list_lock6FpnJBasicLock__v_ (c807f7d4, ff170000, d4680000, 4491d4, fee1bc2c,
    0) + 78
    fee3167c __1cPVM_GC_OperationNdoit_prologue6M_i_ (c807f7bc, 4400, ff170000, 2d2b8, 4a6268, c807fa18) + 38
    fee2e0b0 __1cIVMThreadHexecute6FpnMVM_Operation__v_ (c807f7bc, 963a8, 0, 0, 1, 0) + 90
    fed2c2a4 __1cbCTwoGenerationCollectorPolicyRmem_allocate_work6MIii_pnIHeapWord__ (962c0, ff1c29ec, ff1c297c, ff131a26, 4800, 4998) + 160
    fed22940 __1cNinstanceKlassRallocate_instance6MpnGThread__pnPinstanceOopDesc__ (ee009020, 5941d0, 15ca581, 3647f0, 4a6268, c807f8c8) + 180
    fed34928 __1cLOptoRuntimeFnew_C6FpnMklassOopDesc_pnKJavaThread__v_ (ee009018, 5941d0, 0, 0, 0, 0) + 28
    fa435a58 ???????? (ee009018, e86de, 15ca4de, 50dc, 5941d0, c807f9c8)
    fb36f9a4 ???????? (0, d412ccd8, ee046c28, ff170000, 0, 0)
    fad8b278 ???????? (ee046c28, d6000c90, ee046530, 8, db8e8450, c807f9e8)
    fad62abc ???????? (d412ccd8, ee046530, d6000c90, ee3bfa38, 8, c807fa18)
    fa4b3c38 ???????? (c807fb9c, 0, f2134700, fa415e50, 8, c807faa8)
    fa40010c ???????? (c807fc28, c807fe90, a, ee9e1e20, 4, c807fb40)
    fed5d48c __1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_ (c807fe88, c807fcf0, c807fda8, 5941d0, 5941d0, c807fd00) + 27c
    fee4b784 __1cJJavaCallsMcall_virtual6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_ (ff170000, 594778, c807fd9c, c807fd98, c807fda8, 5941d0) + 164
    fee5e8dc __1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_5pnGThread__v_ (c807fe88, c807fe84, c807fe7c, c807fe74, c807fe6c, 5941d0) + 6c
    fee6fc74 __1cMthread_entry6FpnKJavaThread_pnGThread__v_ (5941d0, 5941d0, 838588, 594778, 306d10, fee69254) + 128
    fee6927c __1cKJavaThreadDrun6M_v_ (5941d0, 2c, 40, 0, 40, 0) + 284
    fee6575c _start   (5941d0, fa1a1600, 0, 0, 0, 0) + 134
    ff3758c0 lwpstart (0, 0, 0, 0, 0, 0)
    =============================================================================================
    Also when it's having this problem, the "VM Thread" is always using a lot of processor time. We did a couple of pstacks today while it was having this problem, and this thread was stuck in the ONMethodSweeper.sweep for over 15 minutes when we finally killed the server.
    From the thread dump:
    "VM Thread" prio=5 tid=0x000e2d20 nid=0x2 runnable
    From the first pstack:
    =============================================================================================
    ----------------- lwp# 2 / thread# 2 --------------------
    fed40c04 __1cXvirtual_call_RelocationIparse_ic6FrpnICodeBlob_rpC5rppnHoopDesc_pi_nNRelocIterator__ (42a2f4, fa5fa46d, ffffffff, fc4ffcb8, 42a2f4, 42a324) + 124
    fed46318 __1cKCompiledIC2t5B6MpnKRelocation__v_ (42a2f0, fc4ffd24, fc4ffd4c, e802, 0, 6) + 38
    fed90c38 __1cHnmethodVcleanup_inline_caches6M_v_ (fa5f7f88, fa608940, 1, 0, fa400000, 6) + 1ac
    fede18b4 __1cONMethodSweeperFsweep6F_v_ (2cf38, 0, ffffffff, ff1cf1fc, ff1c66e8, fede1d44) + 1b0
    fede1e6c __1cUSafepointSynchronizeFbegin6F_v_ (2cf38, ff1ba138, 5000, 50dc, 5000, 525c) + 248
    feef1fd4 __1cIVMThreadEloop6M_v_ (4400, 4000, 4324, 4000, 42b0, 3800) + 3d4
    feef1ae4 __1cIVMThreadDrun6M_v_ (e2d20, 2, 40, 0, 40, 0) + 8c
    fee6575c _start   (e2d20, ff270200, 0, 0, 0, 0) + 134
    ff3758c0 lwpstart (0, 0, 0, 0, 0, 0)
    =============================================================================================
    Second pstack
    =============================================================================================
    ----------------- lwp# 2 / thread# 2 --------------------
    fed41180 __1cXvirtual_call_RelocationIparse_ic6FrpnICodeBlob_rpC5rppnHoopDesc_pi_nNRelocIterator__ (0, ff1b9664, ffffffff, fc4ffcb8, a6f2cc, fc4ffbd0) + 6a0
    fed46318 __1cKCompiledIC2t5B6MpnKRelocation__v_ (a6f2c8, fc4ffd24, fc4ffd4c, e802, 0, 6) + 38
    fed90c38 __1cHnmethodVcleanup_inline_caches6M_v_ (faded4c8, fadf2c80, 1, 0, fa400000, 6) + 1ac
    fede18b4 __1cONMethodSweeperFsweep6F_v_ (2cf38, 0, ffffffff, ff1cf1fc, ff1c66e8, fede1d44) + 1b0
    fede1e6c __1cUSafepointSynchronizeFbegin6F_v_ (2cf38, ff1ba138, 5000, 50dc, 5000, 525c) + 248
    feef1fd4 __1cIVMThreadEloop6M_v_ (4400, 4000, 4324, 4000, 42b0, 3800) + 3d4
    feef1ae4 __1cIVMThreadDrun6M_v_ (e2d20, 2, 40, 0, 40, 0) + 8c
    fee6575c _start   (e2d20, ff270200, 0, 0, 0, 0) + 134
    ff3758c0 lwpstart (0, 0, 0, 0, 0, 0)
    =============================================================================================
    Has anyone ever seen anything like this? I'm trying to figure out if this is caused by something we're doing, or something relating to our environment and jvm options. Any ideas?

    Thanks for the reply - I'm testing our app with the +UseConcMarkSweepGC now in our test environment to make sure it doesn't cause any problems there.  Unfortunately the only place we've had this problem is on the production server, so it's extra difficult debugging this. 
    We're using the following memory options:
    -ms512m -mx512m -XX:NewSize=128m -XX:PermSize=192m -XX:MaxNewSize=128m -XX:MaxPermSize=192m -XX:SurvivorRatio=8and the following debugging options, as we've also been seeing OutOfMemoryErrors ( see http://forum.java.sun.com/thread.jsp?forum=37&thread=522354&tstart=45&trange=15 )
    -verbosegc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGCBTW, which c++filt version and options are you using? Our Solaris boxes only seem to have the GNU version installed. I was trying to run that on some of the other stack traces and wasn't getting anywhere, and didn't know if because it was GNU version wouldn't work on something compiled with the Sun compiler.
    Thanks!
    --Andy                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • "Portable" way to do message passing between threads?

    (I posted this on the Apple Developer Forums already, but since that forum is only accessible to registered and paid iPhone developers, I thought it would be nice to put it here as well so as to get some more potential eyeballs on it. I apologize if this kind of "cross-posting" is not kosher/is frowned upon around here.)
    Hey everybody,
    "Long-time listener, first-time caller," heh.
    I've been working for the past 2-3 months on my very first iPhone app. Actually, what I've been working on is a framework that I plan to use in an iPhone app of my own but which I am also trying to write for the "lowest-common-denominator" so that I (and others) can use it in other apps written for both Mac and iPhone.
    Not only is this my first time writing an iPhone app, it is my first time writing for any Apple platform. In fact, it is my first time using Objective-C, period. I cannot stress this enough: I am a "n00b." So go easy on me. I also have not worked with threading before this, either, on any platform, so the learning curve for me here is rather significant, I'm afraid. I am NOT afraid of either taking the time to learn something properly OR of rolling up my shirtsleeves and working. However, on account of my experiences so far, I am finding myself (not to flame or anything!) quickly becoming frustrated by and disillusioned with not so much Objective-C itself, but the Foundation frameworks.
    So with that said, read on, if you dare...
    The basic idea behind my project is that the framework I am writing will present an API to developers which will allow them to write client apps that interact with a particular network appliance or network-aware embedded system. I already have my basic set of classes up and functioning, and the framework works to my satisfaction both on MacOS and iPhoneOS. The platforms I am targeting are MacOS X Tiger 10.4 and later, and iPhoneOS, and up until this point, I've managed to keep a codebase that works on all of the above.
    What I wanted to do next was add some multithreaded goodness to the mix. (Woe is me.) I have asynchronous network socket I/O working within the main thread, and it, in fact, works a treat. In my test app on the phone, I've managed to keep the UI nice and responsive by using the main thread's runloop efficiently. But even though TCP async I/O works fine within the main thread, I want to be able to split out and offload the processing of any data received by the app from the appliance to its own thread. (It is possible, and even desirable, for an application using this framework to be connected to multiple appliances simultaneously.)
    My idea, in order to try to keep things as simple and as clean as possible, was to implement a wrapper class that presented my other main class as an "actor." So, rather than instantiating my main class, one would create an instance of the wrapper class which would in turn control a single instance of my main class and spawn its own thread that the network connection and all data processing for that particular connection would run within.
    (I hope I'm making sense so far...)
    Out of the gate, writing a subclass of NSThread sounds like the logical design choice for an "actor-type" thread, but because I was trying to maintain Tiger compatibility, I stuck with +detachNewThreadSelector:etc.
    Once I decided to pursue the actor model, though, the main problem presented itself: how to best pass messages between the main thread and all of the "actor" threads that might be spawned?
    I stumbled upon -performSelector:onThread:withObject:, and knew instantly that this was exactly what I was looking for. Unfortunately, it doesn't exist on Tiger; only its much more limited little brother -performSelectorOnMainThread:withObject: does. So I kept looking.
    All of the pre-Leopard documentation, tutorials, and sample code that I read indicated that to pass messages between threads, I needed to basically pretend that the threads were separate processes and use the expensive Distributed Objects mechanism to get messages back and forth. Unfortunately, even if that WAS a desirable option, iPhoneOS does not have any support for DO! Grrr...
    Finally, I thought I found the answer when I ran into a third-party solution: the InterThreadMessaging library from Toby Paterson (available @ http://homepage.mac.com/djv/FileSharing3.html). In this library, the author basically implemented his own version of -performSelector:onThread:withObject: called -performSelector:withObject:inThread:. Sounds close enough, right? And actually, it is pretty darn close. It's made to do exactly what it sounds like, and it does it in a platform-neutral way that works on pre-Leopard systems as well as iPhoneOS, using Mach ports instead of DO.
    (...wellll, ALMOST. I discovered after I built a small test app around it that it actually isn't "iPhone-clean." The author used an NSMapTable struct and the NSMap*() functions, which don't exist in iPhoneOS, and he also implemented the handlePortMessage delegate method, but although iPhoneOS has NSPort, it DOESN'T have NSPortMessage. GAAARGH. So I took the time to replace the NSMapTable stuff with NSValue-wrapped objects inside of an NSMutableDictionary, and replaced the handlePortMessage method implementation with a handleMachMessage method, which took some doing because I had to figure out the structure of a Mach message, NO thanks to ANY of the available documentation...)
    Once I started using it, though, I quickly discovered that this implementation wasn't up to snuff. My "actor" class and my main thread will be passing a ton of messages to each other constantly whenever there is network activity, and with InterThreadMessaging, I found that whenever activity started to ramp up, it would collapse on itself. This mostly took the form of deadlocks. I found a note that someone else wrote after experiencing something similar with this library (quoted from DustinVoss @ http://www.cocoadev.com/index.pl?InterThreadMessaging):
    "It is possible to deadlock this library if thread A posts a notification on thread B, and the notification on B causes a selector or notification to be posted on thread A. Possibly under other circumstances. I have resolved this in my own code by creating an inter-thread communication lock. When a thread wants to communicate, it tries the lock to see if another thread is already using the InterThreadMessaging library, and if it can't get the lock, it posts a message to its own run-loop to try again later. This is not a good solution, but it seems to work well enough."
    So I tried implementing what he described using a global NSLock, and it did help with some of the deadlocks. But not all. I believe the culprit here is the Mach ports system itself (from the NSPortMessage documentation for -sendBeforeDate:):
    "If the message cannot be sent immediately, the sending thread blocks until either the message is sent or aDate is reached. Sent messages are queued to minimize blocking, but failure can occur if multiple messages are sent to a port faster than the portís owner can receive them, causing the queue to fill up."
    InterThreadMessaging in fact calls -sendBeforeDate: and exposes the deadline option, so I tried setting a really short time-to-live on the Mach messages and then intercepted any NSPortTimeoutExceptions that were thrown; upon catching said exceptions, I would then re-queue up the message to be sent again. It worked, but Performance. Was. A. Dog. At least the message queue wouldn't be full indefinitely anymore, causing the main thread to block, but during the whole time that these messages were expiring because the queue was full and then being re-queued, either the main thread was trying to send more messages or the actor thread was trying to send more messages. And as far as I can tell, the Mach ports queue is global (at the very least, there is seemingly only one per process). The message would get through with this model...eventually.
    JUST IN CASE the problem happened to be something I screwed up as I was rewriting portions of the InterThreadMessaging library so that it would compile and work on the iPhone SDK, I substituted in the original version of the library in my Mac test app to see if any of these problems became non-issues. I found that both versions of the library -- mine and the original -- performed identically. So that wasn't it.
    Finally, in frustration I said, "screw it, I'm going to try it the Leopard way," and replaced all of the method calls I was making to InterThreadMessaging's -performSelector:withObject:inThread: with calls to Foundation's native -performSelector:onThread:withObject: instead, changing nothing else within my code in the process. And wouldn't you know: IT WORKED GREAT. Performance was (and is) fantastic, about on-par with the non-threaded version when only dealing with a single connection/instance of my class.
    So, in the end, I was able to do nothing to salvage the InterThreadMessaging implementation of cross-thread method calling, and as far as I can tell, I'm out of (good) options. And thus my mind is filled with questions:
    How is the Leopard -performSelector:onThread: method implemented? I'm guessing not using Mach ports, given that I didn't have the same blocking & deadlocking problems I had with InterThreadMessaging. Is it possible to re-implement this Leopard+ method in a similar manner as a category to NSObject under Tiger? Or is it possible, perhaps, to increase the size of the Mach ports queue so that InterThreadMessaging works at a sane level of performance? Or -- I'm getting desperate here -- is there any way that I could trick -performSelectorOnMainThread: to target a different thread instead? (I am assuming here that -performSelectorOnMainThread is implemented under-the-hood much like the new -performSelector:onThread: is implemented, but with a hard-coded NSThread pointer built-in to the code, and that the new method just exposes a more flexible interface to what is basically the same code. I'm probably wrong...) Is there another third-party library out there that I've missed that fits my requirements for being able to do message-passing between threads in an efficient and portable manner?
    I refuse to believe that there is no way for me to maintain compatibility with all of the platforms I wish to support without having to resort to making preprocessor #ifdef spaghetti out of my code. And there SURELY has to be a better way of doing cross-thread message passing in Tiger without using Distributed Objects, for Pete's sake! Is this really how people did it for years-on-end since the dawn of NeXT up until the advent of Leopard? And if there really, genuinely wasn't another alternative, then what is up with the lack of DO in iPhoneOS?? Does Apple seriously intend for developers who have good, solid, tested and working code to just chuck it all and start over? What if there was some aspect of DO that previous implementations relied upon that cannot be recreated with simple -performSelector:onThread: calls? (I don't know what those aspects would be...just a hypothetical.) I mean, I can understand needing to write new stuff from scratch for your UI given how radically different the interface is between the Mac and iPhone, but having to reimplement back-end guts such as something as elemental as threads...really?!
    I do laud the inclusion of the new method in Leopard as well as the new ability to subclass NSThread itself. But for those of us that need to support Tiger for one reason or another, some of these restrictions and omissions within iPhoneOS seem like rather pointless (and frustrating) roadblocks.
    As I hope is obvious here, I have tried to do my homework before throwing up my hands and pestering y'all. If you have the patience to deal with me, please tell me what I am missing.
    Thanks for taking the time to read,
    -- Nathan

    Thanks again for your patience. Comments below.
    etresoft wrote:
    It is pretty unusual that anyone would want to call perfomrSelector on any thread other than the main thread.
    What I described in my original post was not a worker thread, but an "actor."
    It is hard for me to answer this question because there are so many options available to do "message passing". The fact that you think there are so few tells me that you really aren't sure what you need to use.
    I didn't say there were few options for message passing. I said there were few options for message passing that fit my criteria, which are that any potential solutions should both A) work efficiently and with good performance, and B) be available both pre-Leopard AND on the iPhone. -performSelector: ain't available before Leopard. Distributed Objects is overkill. Kernel Mach messages apparently have a high overhead, too, as my experience with the third-party library I wrote about in my original message shows.
    ...consider notifications.
    I thought notifications couldn't be posted across threads, either. How do I post a notification to another thread's default notification center or notification queue from a different thread?
    The notification center is owned by the process. Each run loop can listen for just the notifications it wants. You don't "pass" or "send" notifications, you run then up the flagpole for all to see.
    I am aware of how to use notifications. The documentation for NSNotificationCenter clearly states that "In a multithreaded application, notifications are always delivered in the thread in which the notification was posted, which may not be the same thread in which an observer registered itself."
    So, again, I don't see how one thread can post a notification in such a way that the observer's registered method is executed in another thread (posting notifications "across threads"). This probably isn't a big deal if you are using mutexes (assuming you don't actually care which thread carries out the task associated with the notification posting), but as I said before, this is not what I'm after.
    I don't know what you are really after.
    Allow me to attempt to explain a second time, in a more concise fashion.
    My app will have multiple, persistent TCP connections open, one connection per remote device. The user will be able to select a task to execute on a particular device that we have a connection open to, and get back from the application real-time updates as to the progress or results of the execution of that task. In certain cases, the length of the task is infinite; it will keep executing forever and sending back results to my application which will update its display of the results every second that ticks by until the user STOPS that particular task.
    This can be done simply using async I/O in the main runloop, sure. But if I were going to thread this so that I could be processing the results I've received back from one *or more* remote devices while also doing something else, given that I will only have one (persistent) connection open to any given remote device that I'm interacting with (that is to say, I won't be opening up a separate TCP session for every single task I want to execute on a single device simultaneously), it makes sense _to me_ to implement this as I've described: with every connection to each remote device getting its own thread that lasts for the lifetime of the TCP session (which could be the entire time the application is running, times however many devices the user wishes to be connected to while in the app). I won't be spawning a new thread for every task the user wishes to ask a remote device to do.
    This is why (I think) I need bi-directional messaging between the main thread and each of these threads dedicated to a given remote device that we have an active session with/connection to. The main thread needs to be able to tell remote device X (which already has a running thread dedicated to it) to do task A, and then get real-time feedback from that remote device so that the main thread can be displaying it to the user as it is coming back. Same with remote device Y running task B, simultaneously. At any time during the execution of these tasks, the user needs to be able to tell my app to stop one of these tasks, and the main thread needs to send that message to one of the remote devices via that device's dedicated thread.
    This is why I am talking about this in terms of the "actor model," and not the "worker thread model," because the former model seems to fit what I want to do.
    -- Nathan

  • "error: thread-local storage not supported for this target"

    I have a program that uses the __thread specifier, to be run on a Solaris 9/UltraSprac.
    I am not able to compile it using gcc 3.4.4 or 4.0.4, it emits the msg "error: thread-local storage not supported for this target".
    xz@gamera% gcc -v -Wall -D_REENTRANT -c -o func_stack.o func_stack.c
    Reading specs from /opt/gcc/3.4.4/lib/gcc/sparc-sun-solaris2.8/3.4.4/specs
    Configured with: ../srcdir/configure --prefix=/opt/gcc/3.4.4 --disable-nls
    Thread model: posix
    gcc version 3.4.4
    /opt/gcc/3.4.4/libexec/gcc/sparc-sun-solaris2.8/3.4.4/cc1 -quiet -v -D_REENTRANT -DMESS func_stack.c -quiet -dumpbase func_stack.c -mcpu=v7 -auxbase-strip func_stack.o -Wall -version -o /var/tmp//cc0poHSN.s
    ignoring nonexistent directory "/usr/local/include"
    ignoring nonexistent directory "/opt/gcc/3.4.4/lib/gcc/sparc-sun-solaris2.8/3.4.4/../../../../sparc-sun-solaris2.8/include"
    #include "..." search starts here:
    #include <...> search starts here:
    /opt/gcc/3.4.4/include
    /opt/gcc/3.4.4/lib/gcc/sparc-sun-solaris2.8/3.4.4/include
    /usr/include
    End of search list.
    GNU C version 3.4.4 (sparc-sun-solaris2.8)
            compiled by GNU C version 3.4.4.
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
    func_stack.c:16: error: thread-local storage not supported for this target
    func_stack.c:17: error: thread-local storage not supported for this target
    func_stack.c:19: error: thread-local storage not supported for this target
    xs@gamera% gcc -v -D_REENTRANT  -c -o func_stack.o func_stack.c
    Using built-in specs.
    Target: sparc-sun-solaris2.9
    Configured with: /net/clpt-v490-0/export/data/bldmstr/20070711_mars_gcc/src/configure --prefix=/usr/sfw --enable-shared --with-system-zlib --enable-checking=release --disable-libmudflap --enable-languages=c,c++ --enable-version-specific-runtime-libs --with-cpu=v9 --with-ld=/usr/ccs/bin/ld --without-gnu-ld
    Thread model: posix
    gcc version 4.0.4 (gccfss)
    /pkg/gcc/4.0.4/bin/../libexec/gcc/sparc-sun-solaris2.9/4.0.4/cc1 -quiet -v -I. -iprefix /pkg/gcc/4.0.4/bin/../lib/gcc/sparc-sun-solaris2.9/4.0.4/ -D__sparcv8 -D_REENTRANT -DMESS func_stack.c -quiet -dumpbase func_stack.c -mcpu=v9 -auxbase-strip func_stack.o -version -m32 -o /tmp/ccjsdswh.s -r /tmp/cc2w4ZRo.ir
    ignoring nonexistent directory "/pkg/gcc/4.0.4/bin/../lib/gcc/sparc-sun-solaris2.9/4.0.4/../../../../sparc-sun-solaris2.9/include"
    ignoring nonexistent directory "/usr/local/include"
    ignoring nonexistent directory "/usr/sfw/lib/gcc/sparc-sun-solaris2.9/4.0.4/include"
    ignoring nonexistent directory "/usr/sfw/lib/../sparc-sun-solaris2.9/include"
    #include "..." search starts here:
    #include <...> search starts here:
    /pkg/gcc/4.0.4/bin/../lib/gcc/sparc-sun-solaris2.9/4.0.4/include
    /usr/sfw/include
    /usr/include
    End of search list.
    GNU C version 4.0.4 (gccfss) (sparc-sun-solaris2.9)
            compiled by GNU C version 4.0.4 (gccfss).
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
    func_stack.c:16: error: thread-local storage not supported for this target
    func_stack.c:17: error: thread-local storage not supported for this target
    func_stack.c:19: error: thread-local storage not supported for this targetJust as comparison, the corresponding output of compiling another file which does not have __thread declaration is as follows:
    xz@gamera% gcc -v -Wall -D_REENTRANT -c -o common.o common.c
    Reading specs from /opt/gcc/3.4.4/lib/gcc/sparc-sun-solaris2.8/3.4.4/specs
    Configured with: ../srcdir/configure --prefix=/opt/gcc/3.4.4 --disable-nls
    Thread model: posix
    gcc version 3.4.4
    /opt/gcc/3.4.4/libexec/gcc/sparc-sun-solaris2.8/3.4.4/cc1 -quiet -v -D_REENTRANT -DMESS common.c -quiet -dumpbase common.c -mcpu=v7 -auxbase-strip common.o -Wall -version -o /var/tmp//cc4VxrLz.s
    ignoring nonexistent directory "/usr/local/include"
    ignoring nonexistent directory "/opt/gcc/3.4.4/lib/gcc/sparc-sun-solaris2.8/3.4.4/../../../../sparc-sun-solaris2.8/include"
    #include "..." search starts here:
    #include <...> search starts here:
    /opt/gcc/3.4.4/include
    /opt/gcc/3.4.4/lib/gcc/sparc-sun-solaris2.8/3.4.4/include
    /usr/include
    End of search list.
    GNU C version 3.4.4 (sparc-sun-solaris2.8)
            compiled by GNU C version 3.4.4.
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
    /usr/ccs/bin/as -V -Qy -s -xarch=v8 -o common.o /var/tmp//cc4VxrLz.s
    /usr/ccs/bin/as: Sun WorkShop 6 update 2 Compiler Common 6.2 Solaris_9_CBE 2001/04/02Note that the last 2 lines seem to suggest that a Sun assembler is used as the back-end of gcc. I am not sure whether the failure to compile the first file (with __thread) was due to the incompatibility of this Sun assembler. In the first case, the error msg was emitted before these 2 lines are printed.
    I further read a post about gcc 3.3.3's inability to compile code that has __thread in it, on a HP-UX 11.11: http://forums12.itrc.hp.com/service/forums/questionanswer.do?admit=109447627+1216595175060+28353475&threadId=1148976 The conclusion seems to suggest that "the 2.17 GNU assembler did not support thread local storage" and gcc sees that and thus disallows TLS.
    If the assembler is the culprit, then does anyone know whether this "Sun WorkShop 6 update 2" assembler in my installation can work with TLS? And how come a Sun assembler becomes the back-end of gcc? I read that gas (the GNU assembler) is the default backend of gcc. (How) can one specify the assembler to be used for gcc?
    As an aside, I am able to compile my file on this same Solaris 9/UltraSparc platform using the Sun Studio 12 C Compiler:
    xz@gamera% cc -V -# -D_REENTRANT  -c -o func_stack.o func_stack.c
    cc: Sun C 5.9 SunOS_sparc Patch 124867-01 2007/07/12
    ### Note: NLSPATH = /pkg/SUNWspro/12/prod/bin/../lib/locale/%L/LC_MESSAGES/%N.cat:/pkg/SUNWspro/12/prod/bin/../../lib/locale/%L/LC_MESSAGES/%N.cat
    ###     command line files and options (expanded):
    ### -c -D_REENTRANT  -V func_stack.c -o func_stack.o
    /pkg/SUNWspro/12/prod/bin/acomp -xldscope=global -i func_stack.c -y-fbe -y/pkg/SUNWspro/12/prod/bin/fbe -y-xarch=generic -y-xmemalign=8i -y-o -yfunc_stack.o -y-verbose -y-xthreadvar=no%dynamic -y-comdat -xdbggen=no%stabs+dwarf2+usedonly -V -D_REENTRANT  -m32 -fparam_ir -Qy -D__SunOS_5_9 -D__SUNPRO_C=0x590 -D__SVR4 -D__sun -D__SunOS -D__unix -D__sparc -D__BUILTIN_VA_ARG_INCR -D__C99FEATURES__ -Xa -D__PRAGMA_REDEFINE_EXTNAME -Dunix -Dsun -Dsparc -D__RESTRICT -xc99=%all,no%lib -D__FLT_EVAL_METHOD__=0 -I/pkg/SUNWspro/12/prod/include/cc "-g/pkg/SUNWspro/12/prod/bin/cc -V -D_REENTRANT  -c -o func_stack.o " -fsimple=0 -D__SUN_PREFETCH -destination_ir=yabe
    acomp: Sun C 5.9 SunOS_sparc Patch 124867-01 2007/07/12Interestingly, the output no longer mentions the "/usr/ccs/bin/as: Sun WorkShop 6 update 2" assembler.

    Just as another comparison, I compiled a file without __thread on the Solaris 9/UltraSparc platform using gcc 4.0.4. Not surprisingly it worked. But I no longer see the mention of the Sun assembler as in the case of gcc 3.4.4. Nor did I see the mention of "GNU assembler" as in the case of gcc 4.0.4/Solaris 10/x86. Instead, I saw something called "iropt" and "cg". Does anyone know what they are?
    xz@gamera% gcc -v -Wall -D_REENTRANT -c -o common.o common.c
    Using built-in specs.
    Target: sparc-sun-solaris2.9
    Configured with: /net/clpt-v490-0/export/data/bldmstr/20070711_mars_gcc/src/configure --prefix=/usr/sfw --enable-shared --with-system-zlib --enable-checking=release --disable-libmudflap --enable-languages=c,c++ --enable-version-specific-runtime-libs --with-cpu=v9 --with-ld=/usr/ccs/bin/ld --without-gnu-ld
    Thread model: posix
    gcc version 4.0.4 (gccfss)
    /pkg/gcc/4.0.4/bin/../libexec/gcc/sparc-sun-solaris2.9/4.0.4/cc1 -quiet -v -iprefix /pkg/gcc/4.0.4/bin/../lib/gcc/sparc-sun-solaris2.9/4.0.4/ -D__sparcv8 -D_REENTRANT -DMESS common.c -quiet -dumpbase common.c -mcpu=v9 -auxbase-strip common.o -Wall -version -m32 -o /tmp/ccSGJIDD.s -r /tmp/ccKuJz76.ir
    ignoring nonexistent directory "/pkg/gcc/4.0.4/bin/../lib/gcc/sparc-sun-solaris2.9/4.0.4/../../../../sparc-sun-solaris2.9/include"
    ignoring nonexistent directory "/usr/local/include"
    ignoring nonexistent directory "/usr/sfw/lib/gcc/sparc-sun-solaris2.9/4.0.4/include"
    ignoring nonexistent directory "/usr/sfw/lib/../sparc-sun-solaris2.9/include"
    #include "..." search starts here:
    #include <...> search starts here:
    /pkg/gcc/4.0.4/bin/../lib/gcc/sparc-sun-solaris2.9/4.0.4/include
    /usr/sfw/include
    /usr/include
    End of search list.
    GNU C version 4.0.4 (gccfss) (sparc-sun-solaris2.9)
            compiled by GNU C version 4.0.4 (gccfss).
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
    /pkg/gcc/4.0.4/SUNW0scgfss/4.0.4/prod/bin/iropt -F -xarch=v8plus -xchip=generic -O1 -xvector=no -xbuiltin=%none -xcache=generic -Qy -h_gcc -o /tmp/ccUl4mVM.ircg /tmp/ccKuJz76.ir -N/dev/null -is /tmp/ccSGJIDD.s
    /pkg/gcc/4.0.4/SUNW0scgfss/4.0.4/prod/bin/cg -Qy -xarch=v8plus -xchip=generic -OO0 -T3 -Qiselect-C0 -Qrm:newregman:coalescing=0 -xcode=abs32 -xcache=generic -xmemalign=8i -il /pkg/gcc/4.0.4/bin/../lib/gcc/sparc-sun-solaris2.9/4.0.4//gccbuiltins.il -xvector=no -xthreadvar=no%dynamic -xbuiltin=%none -Qassembler-ounrefsym=0 -Qiselect-T0 -Qassembler-I -Qassembler-U -comdat -h_gcc -is /tmp/ccSGJIDD.s -ir /tmp/ccUl4mVM.ircg -oo common.o

  • Issue: BPEL invoking Axis web service

    Hi
    We are calling a Axis web service from BPEL.. The web service has been defined to be a request only 1 way service. The axis service takes around 3-5 minutes to complete the job( data insertion in DB).. But seems like when BPEL invokes the web service; BPEL thread is waiting (thread is not released) and the BPEL process does not move forward until the web service completes the job....
    Any pointers on how the deal with the issue will be helpful!!
    Thanks

    Hi Lovenish,
    Goto console-> select domain> Configuration->JTA
    Check timeout seconds.
    2. i don't know what kind of partner link you are invoking.
    check composite.xml, is there any property like retry.interval .
    3. ◦SyncMaxWaitTime: The maximum time a request and response operation takes before timing out.
    The maximum time a request/response operation will take before it times out. The default value is 45 seconds.
    Regards,
    Padmanabham

  • Export from Crystal Reports 2008 viewer fails if run on separate thread

    I have a windows desktop application written in Visual Basic using Visual Studio 2008.  I have installed and am trying Crystal Reports 2008 to run a report.  Everything seems to work well except that when I preview a report (using the viewer control) and click the export button found in the upper left corner of that control, I get the following message:
    Error 5: Current thread must be set to single thread apartment (STA) mode before OLE calls can be made.  Ensure that your Main function has STAThreadAttribute marked on it.  This exception is only raised if a debugger is attached to the process.
    I am a little confused on what to do exactly.  Is the problem because I am running in the Visual Studio 2008 IDE?  It says this exception is only raise if a debugger is attached to the process.  No, I tried running it outside the IDE.  The exception wasn't generated but the application hung when the button was clicked.
    It says the current thread must be set to single thread apartment (STA) mode.  If the report is run on its own thread, is the "current" thread the thread the report is running on or is the main application's UI thread?  I don't think I want to set my main application to single thread apartment mode because it is a multi-threaded application (although I really don't know for sure because I am new to multi-threaded programming). 
    My objective is to allow reports to run asynchronously so that the user can do other things while it is being generated.  Here is the code I use to do this:
        ' Previews the report using a new thread (asynchronously)
        Public Sub PreviewReportAsynch(ByVal sourceDatabase As clsMainApplicationDatabase)
            Dim backgroundProcess As System.ComponentModel.BackgroundWorker
            ' Start a new thread to run this report.
            backgroundProcess = New System.ComponentModel.BackgroundWorker
            Using (backgroundProcess)
                ' Wire the function we want to run to the 'do work' event.
                AddHandler backgroundProcess.DoWork, AddressOf PreviewReportAsynch_Start
                ' Kick off the report asynchronously and return control to the calling process
                backgroundProcess.RunWorkerAsync(sourceDatabase)
            End Using
        End Sub
        Private Sub PreviewReportAsynch_Start(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
            ' The source database needed to call preview report was passed as the only argument
            Call PreviewReport(CType(e.Argument, clsMainApplicationDatabase))
        End Sub
        ' Previews the report.  From the preview window, the user can print it.
        Public Function PreviewReport(ByVal sourceDatabase As clsMainApplicationDatabase) As FunctionEndedResult
            Dim errorBoxTitle As String
            Dim frmPreview As frmReportPreview
            ' Setup error handling
            errorBoxTitle = "Preview " & Name & " Report"
            PreviewReport = FunctionEndedResult.FAILURE
            On Error GoTo PreviewError
            ' Set up the crxReport object
            If InitializeReportProcess(sourceDatabase) <> FunctionEndedResult.SUCCESS Then
                GoTo PreviewExit
            End If
            ' Use the preview form to preview the report
            frmPreview = New frmReportPreview
            frmPreview.Report = crxReport
            frmPreview.ShowDialog()
            ' Save any settings that should persist from one run to the next
            Call SavePersistentSettings()
            ' If we got this far everything is OK.
            PreviewReport = FunctionEndedResult.SUCCESS
    PreviewExit:
            ' Do any cleanup work
            Call CleanupReportProcess(sourceDatabase)
            Exit Function
    PreviewError:
            ' Report error then exit gracefully
            ErrorBox(errorBoxTitle)
            Resume PreviewExit
        End Function
    The variable crxReport is of type ReportDocument and the windows form called 'frmPreview' has only 1 control, the crystal reports viewer. 
    The print button on the viewer works fine.  Just the export button is failing.  Any ideas?

    Hi Trevor.
    Thank you for the reply.  The report document is create on the main UI thread of my application.  The preview form is created and destroyed on the separate thread.  For reasons I won't get into, restructuring the code to move all the initialization stuff inside the preview form is not an option (OK, if you a really curious, I don't always preview a report, sometimes I print and/or export it directly which means the preview form isn't used).
    What I learned through some other research is that there are some things (like COM calls and evidently some OLE automation stuff) that cannot be run on a thread that uses the MTA threading model.   The export button probably uses some of this technology, thus the message stating that an STA threading model is required.  I restructured the code as follows to accomodate this requirement.  Here is a sample:
    ' Previews the report using a new thread (asynchronously)
        Public Sub PreviewReportAsynch(ByVal sourceDatabase As clsMainApplicationDatabase)
            Dim staThread As System.Threading.Thread
            ' Start the preview report function on a new thread
            staThread = New System.Threading.Thread(AddressOf PreviewReportAsynchStep1)
            staThread.SetApartmentState(System.Threading.ApartmentState.MTA)
            staThread.Start(sourceDatabase)
        End Sub
        Private Sub PreviewReportAsynchStep1(ByVal sourceDatabase As Object)
            Dim staThread As System.Threading.Thread
            ' Initialize report preview.  This includes staging any data and configuring the
            ' crystal report document object for use by the crystal report viewer control.
            If InitializeReportProcess(DirectCast(sourceDatabase, clsMainApplicationDatabase)) = FunctionEndedResult.SUCCESS Then
                ' Show the report to the user.  This must be done on an STA thread so we will
                ' start another of that type.  See description of PreviewReportAsynchStep2()
                staThread = New System.Threading.Thread(AddressOf PreviewReportAsynchStep2)
                staThread.SetApartmentState(System.Threading.ApartmentState.STA)
                staThread.Start(mcrxReport)
                ' Wait for step 2 to finish.  This blocks the current thread, but this thread
                ' isn't the main UI thread and this thread has no UI anymore (the progress
                ' form was closed) so it won't matter that is it blocked.
                staThread.Join()
                ' Save any settings that should persist from one successful run to the next
                Call SavePersistentSettings()
            End If
            ' Release the crystal report
            Call CleanupReportProcess(DirectCast(sourceDatabase, clsMainApplicationDatabase))
        End Sub
        ' The preview form must be launched on a thread that use the single-threaded apartment (STA) model.
        ' Threads use the multi-threaded apartment (MTA) model by default.  This is necessary to make the
        ' export and print buttons on the preview form work.  They do not work when running on a
        ' thread using MTA.
        Public Sub PreviewReportAsynchStep2(ByVal crxInitializedReport As Object)
            Dim frmPreview As frmReportPreview
            ' Use the preview form to preview the report.  The preview form contains the crystal reports viewer control.
            frmPreview = New frmReportPreview
            frmPreview.Report = DirectCast(crxInitializedReport, ReportDocument)
            frmPreview.ShowDialog()
        End Sub
    Thanks for your help!
    Andy

Maybe you are looking for