[Asterisk-Dev] Changing Asterisk's module invocation

David Pollak dpp-asterisk at projectsinmotion.com
Wed Sep 15 16:38:32 MST 2004


Juan Jose,

You should only have 1 JVM instance.  You can put a pointer to your JVM 
instance in a static (I forgot the C name for statics... sorry) variable 
that can be accessed by any caller into your app.

You do a lookup for the "cookie" (the void * that you proposed in your 
suggested change) based on the unique ID of the channel.

My strong recommendation for destroying the cookie when you destroy the 
channel comes from making sure that there's no memory leak in the JVM 
(or more specifically, no reference leak.)  The cookie that you're 
storing probably corresponds to a Java Object.  That Object is marked as 
referred to by an external JNI program (thus it will not be garbage 
collected from the JVM.)  Once the channel in Asterisk is destroyed, 
you'll have to let the JVM know that the corresponding Java Object (and 
its referenced object) can be garbage collected.

With all that being said, I'd recommend against running a JVM in the 
Asterisk process.  First, the JVM is not as stable as Asterisk. (As a 
side-note, I'm a huge fan of Java.  I was the first technologist to use 
Java in a production system -- WebLogic ran NetGuide Live [the 11th most 
trafficked site on the Internet] back in 1996. I wrote the worlds 
fastest spreadsheet in Java.  I think Java and the JVM are the best 
combination for doing non-realtime systems.  On the other hand, I'm 
realistic about Java's weaknesses as well.)  If the JVM goes down (and 
JVMs go down in production once or twice a month), the Asterisk process 
goes down.  That's bad.  Second, I don't know if the Sun JVM uses the 
same thread primitives as Asterisk.  If it doesn't, there'll be lots of 
weird memory corruption, etc.  Third, when the JVM does garbage 
collection, it halts the current thread (and any other thread that's 
doing a memory allocation -- which is all the time in a JVM.)  Asterisk 
mixes the media and logic on the same thread.  You *have* to respond to 
the media demands every 20ms.  If the JVM is doing garbage collection 
that takes more than 20ms, you're going to have bad sound quality.

With all that being said, why not use an external Java process that 
communicates over AGI and/or the Manager API to control the channel?  
What kind of application are you writing?

Thanks,

David

Juan Jose Comellas wrote:

>But if I do what you propose, each Java module would be created and destroyed 
>when each channel is created and destroyed. I want to have Java modules that 
>last as long as C modules do and that are not tied to specific channels. 
>
>The problem I'm facing is that I need to map the C callback for each 
>application to multiple Java classes in order to have only one instance of 
>the JVM for all the Java modules. The configuration file would look like 
>this:
>
>--- java.conf 
>[commands]
>JavaTransfer = org.asterisk.JavaTransferModule
>JavaConference = org.asterisk.JavaConferenceModule
>JavaDirectory = org.asterisk.JavaDirectoryModule
>
>So, whenever the any of the commands is found in the dialplan and Asterisk 
>invokes the C callback for my bridge module I would like to invoke a method 
>of the corresponding Java class.
>
>The reason for doing it this way is that I want to be able to dynamically set 
>the Java applications without having to write different C entry points for 
>the different Java Asterisk applications. Do you think this is feasible with 
>the current functionality in Asterisk?
>
>BTW, how can I set up some kind of hook to be notified when Asterisk creates 
>and destroys a channel?
>
>Thanks for your help.
>
>
>On Tuesday 14 September 2004 19:34, David Pollak wrote:
>  
>
>>Juan Jose,
>>
>>You don't need to change Asterisk.  In your glue layer between SWIG and
>>Asterisk, you can determine the unique identifier of the channel.  Based
>>on this unique ID, you can look up the void * data structure in your own
>>store.  Put another way, you manage your own cookies and use the
>>channel's unique ID as the lookup for the cookie.  The only additional
>>bit of work is that you'll have to monitor to see when a channel is
>>destroyed so you can free the cookie entry for the destroyed channel.
>>
>>Depending on exactly what you're using Java for, you might want to take
>>a look at a patch I made (enclosed) to Asterisk.  This patch merges AGI
>>with the Manager API.  It's useful to have a single socket open between
>>a Java app server and Asterisk and control all the Asterisk channels
>>through that socket.
>>
>>If you've got more questions, please feel free to ping me.
>>
>>Thanks,
>>
>>David
>>
>>Juan Jose Comellas wrote:
>>    
>>
>>>I am writing Java bindings for the Asterisk API using SWIG
>>>(http://www.swig.org) so that I can create Asterisk modules written in
>>>Java. The main problem I'm having is that in order to make this process
>>>efficient I need to have more than one application per module (I load
>>>only one instance of the JVM). To be able to build a generic solution
>>>(where I don't have to add one entry point in C per Java application), I
>>>need to make a slight change to the ast_register_application() function
>>>and to the code that invokes each application's callback function.
>>>Currently all application callbacks follow the following prototype:
>>>
>>>int (*execute)(struct ast_channel *, void *data);
>>>
>>>The problem is that when building Java modules this function acts as a
>>>bridge to the Java invocation and I need extra data to be able to map the
>>>call into a Java class/method. To solve this problem I need to make the
>>>following changes to Asterisk's public interface:
>>>
>>>1) Add one argument to the application callback to be able to pass the
>>>"cookie" that will let me map to the Java class/method:
>>>
>>>int (*execute)(struct ast_channel *, void *data, void *cookie);
>>>
>>>2) Change the ast_app struct to be able to store the "cookie". With my
>>>changes it looks like this:
>>>
>>>struct ast_app {
>>>char name[AST_MAX_APP];   /* Name of the application */
>>>int (*execute)(struct ast_channel *chan, void *data, void *cookie);
>>>char *synopsis;    /* Synopsis text for 'show applications' */
>>>char *description;   /* Description (help text) for 'show application
>>><name>' */
>>>void *cookie;    /* Data used to map the call when using Java modules */
>>>struct ast_app *next;   /* Next app in list */
>>>};
>>>
>>>3) Change the ast_register_application() function to pass the cookie to
>>>the ast_app struct:
>>>
>>>int ast_register_application(char *app, int (*execute)(struct ast_channel
>>>*, void *data, void *cookie), char *synopsis, char *description, void
>>>*cookie);
>>>
>>>Do these modifications have any chance of being accepted into Asterisk?
>>>      
>>>
>
>  
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.digium.com/pipermail/asterisk-dev/attachments/20040915/34c23f04/attachment.htm


More information about the asterisk-dev mailing list