Skip to main content

Ansynchron native function is not called a second time using ANILib

1 reply [Last post]
Anonymous

Hi,

I try implement asynchron read/write functions using KNI and ANILib for a
phoneME_feature VM. Unfortunately I did not find much documentation on this
topic, so I got a couple of questions :-)

1. Is there any documentation available appart from chapter 4 of the porting
guide and the small readme.html placed within the anilib sources ?

2. When I used anilib functions the linker complained over unresolved symbols.
So I searched for a switch to enable the linkage, e.g. ENABLE_ANI, but could
not find a corresponding flag. So I added the following line to jvm.make to
make it work:

LINK_FLAGS += -L$(BuildSpace)/$(BUILD_DIR_NAME)/dist/lib -lcldc_vm_ani

Is this the right way to work with anilib ?

3. I implemented a first test function and almost made it work :-) Here is my
code:

typedef struct
{
int _fd;
char _data[512];
int _length;
} MyParameter;

jboolean _firstRun = KNI_TRUE;

static jboolean blockingRead (void* parameter, jboolean is_non_blocking)
{
MyParameter* p = (MyParameter*) parameter;

printf ("is_non_blocking = %d\n", is_non_blocking);
printf ("Doing a blocking read(%d)...\n", p->_fd);
printf ("done!\n");
return KNI_TRUE;
}

/*
* int native readAsync0 (int fd, byte data[]) throws IOException;
*/
KNIEXPORT KNI_RETURNTYPE_INT Java_org_roastedkit_io_RS232Connection_readAsync0
()
{
if (_firstRun == KNI_TRUE)
{
ANI_Initialize ();
_firstRun = KNI_FALSE;
}

if (!ANI_Start ())
{
ANI_Wait ();
KNI_ReturnInt (-1);
}

MyParameter* p = (MyParameter*) ANI_GetParameterBlock (NULL);
printf ("readAsync () - GetParameterBlock returned %p\n", p);
if (p == NULL) // Handle first run.
{
int fd = KNI_GetParameterAsInt (1);
p = (MyParameter*) ANI_AllocateParameterBlock (sizeof(MyParameter));
p->_fd = fd;
p->_length = 0;
memset (p->_data, 0, 512);

if (! ANI_UseFunction (blockingRead, KNI_FALSE))
{
printf ("readAsync () - Blocking thread\n");
ANI_BlockThread ();
goto EXIT;
}
}

printf ("Ready to transmit data back to waiting java thread.\n");

EXIT:
ANI_End ();
KNI_ReturnInt (0);
}

When I call the native function from a java thread, it is suspended and
blockingRead() is called, but afterwards the native function is not called a
second time so the java thread is never released again. I don't know what is
going wrong here ?

Best regards
Sascha

---------------------------------------------------------------------
To unsubscribe, e-mail: feature-unsubscribe@phoneme.dev.java.net
For additional commands, e-mail: feature-help@phoneme.dev.java.net

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Sascha Feldhorst

On Wednesday 26 March 2008 11:23:27 Sascha Feldhorst wrote:
> Hi,
>
> I try implement asynchron read/write functions using KNI and ANILib for a
> phoneME_feature VM. Unfortunately I did not find much documentation on this
> topic, so I got a couple of questions :-)
>
> 1. Is there any documentation available appart from chapter 4 of the
> porting guide and the small readme.html placed within the anilib sources ?
>
> 2. When I used anilib functions the linker complained over unresolved
> symbols. So I searched for a switch to enable the linkage, e.g. ENABLE_ANI,
> but could not find a corresponding flag. So I added the following line to
> jvm.make to make it work:
>
> LINK_FLAGS += -L$(BuildSpace)/$(BUILD_DIR_NAME)/dist/lib -lcldc_vm_ani
>
> Is this the right way to work with anilib ?
>
> 3. I implemented a first test function and almost made it work :-) Here is
> my code:
>
> typedef struct
> {
> int _fd;
> char _data[512];
> int _length;
> } MyParameter;
>
> jboolean _firstRun = KNI_TRUE;
>
> static jboolean blockingRead (void* parameter, jboolean is_non_blocking)
> {
> MyParameter* p = (MyParameter*) parameter;
>
> printf ("is_non_blocking = %d\n", is_non_blocking);
> printf ("Doing a blocking read(%d)...\n", p->_fd);
> printf ("done!\n");
> return KNI_TRUE;
> }
>
> /*
> * int native readAsync0 (int fd, byte data[]) throws IOException;
> */
> KNIEXPORT KNI_RETURNTYPE_INT
> Java_org_roastedkit_io_RS232Connection_readAsync0 ()
> {
> if (_firstRun == KNI_TRUE)
> {
> ANI_Initialize ();
> _firstRun = KNI_FALSE;
> }
>
> if (!ANI_Start ())
> {
> ANI_Wait ();
> KNI_ReturnInt (-1);
> }
>
> MyParameter* p = (MyParameter*) ANI_GetParameterBlock (NULL);
> printf ("readAsync () - GetParameterBlock returned %p\n", p);
> if (p == NULL) // Handle first run.
> {
> int fd = KNI_GetParameterAsInt (1);
> p = (MyParameter*) ANI_AllocateParameterBlock (sizeof(MyParameter));
> p->_fd = fd;
> p->_length = 0;
> memset (p->_data, 0, 512);
>
> if (! ANI_UseFunction (blockingRead, KNI_FALSE))
> {
> printf ("readAsync () - Blocking thread\n");
> ANI_BlockThread ();
> goto EXIT;
> }
> }
>
> printf ("Ready to transmit data back to waiting java thread.\n");
>
> EXIT:
> ANI_End ();
> KNI_ReturnInt (0);
> }
>
> When I call the native function from a java thread, it is suspended and
> blockingRead() is called, but afterwards the native function is not called
> a second time so the java thread is never released again. I don't know what
> is going wrong here ?
>
> Best regards
> Sascha
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: feature-unsubscribe@phoneme.dev.java.net
> For additional commands, e-mail: feature-help@phoneme.dev.java.net

Hi,
I found a solution or better a kind of workaround for my problem and want to
share it. After a couple of tests I figured out, that my ANILib has no own
thread of execution so it has to be triggered to wake up the java threads
again. This is done by calling the function

ANI_WaitForThreadUnblocking (...)

According to the parameters of this function, this has to be done from an
implementation of (see ani_bsd_socket.cpp for an example)

void JVMSPI_CheckEvents(
JVMSPI_BlockedThreadInfo * blocked_threads,
int blocked_threads_count, jlong timeout_milli_seconds)

Unfortunately BSDSocket.cpp already implements this function, so ANILib needs
to be triggered from there. But now it's getting tricky.
ANI_WaitForThreadUnblocking (...) calls
PoolThread_WaitForFinishOrTimeout(...) with a timeout of 0, which has the
effect, that it waits for the i/o thread to finish. This blocks our
JVMSPI_CheckEvents and it's socket specific part can not be executed until
ANILib returns. So a little workaround is needed here. My blocking function
blockingRead(...) uses select with a small timeout to check wether bytes can
be read. If no bytes can be read it sets flag in the MyParameter structure,
which indicates it's KNI counter part
(Java_org_roastedkit_io_RS232Connection_readAsync0) that blockingRead(...)
has to be called again using ANI_UseFunction(...) and ANI_BlockThread(...).
If blockingRead(...) succeeds it indicates this by setting the parameter flag
to true and the result can be passed to the java thread.

Best regards
Sascha

---------------------------------------------------------------------
To unsubscribe, e-mail: feature-unsubscribe@phoneme.dev.java.net
For additional commands, e-mail: feature-help@phoneme.dev.java.net