cancel
Showing results for 
Search instead for 
Did you mean: 

netweaver rfcsdk multi-threading

Former Member
0 Kudos

We have implemented an RFC client (C lang) using the netweaver rfc sdk (currently using sdk v721 p614).

On single-thread environments everything works fine.

But now, we are working on a multi-threaded task that requires several concurrent RFC calls to the backend.

In some cases (let's say on 1-3 out of 8 threads), we get the following error while converting utf8 encoded strings to utf16 (and vice versa) using the provided RfcUTF8ToSAPUC & RfcSAPUCToUTF8 functions:

RFC_ERROR_INFO

code: RFC_CONVERSION_FAILURE (22)

group: EXTERNAL_RUNTIME_FAILURE (5)

message: cannot convert from codepage 4110to codepage 4103

Every thread creates and uses it's own connection to the backend.

Is there anything that has to be done to able to use the sdk on a multi threading enviroment? Are there any limitations?

Thanks in advance

Accepted Solutions (1)

Accepted Solutions (1)

isaias_freitas
Advisor
Advisor
0 Kudos

Hello Loannis,

As far as I know the SDK has no limitations about running in a multi threading environment.

Can you share a sample code that would reproduce the issue?

And could you capture the issue while collecting detailed RFC and CPIC traces?

You can enable these traces by setting the following environment variables for the user that executes your RFC-enabled program:

     CPIC_TRACE=3

     CPIC_TRACE_DIR=<path to log folder>

     RFC_TRACE=3

     RFC_TRACE_DIR=<path to log folder>

The folder indicated above as "<path to log folder>" must be created first, of course, and the user that executes the RFC-enabled program must have write/full access to it.

You can compress ("zip") all logs and attach the compressed file to this thread.

Regards,

Isaías

Former Member
0 Kudos

Hello Isaias,

Thank you for your response. I got it working after some recoding. It seems there was a memory handilng issue on our client.

Again, thank you!

isaias_freitas
Advisor
Advisor
0 Kudos

Hello Loannis,

You're welcome! And glad to hear that the issue is solved .

Regards,

Isaías

Answers (2)

Answers (2)

Former Member
0 Kudos

Update:

putting a pthread mutex lock/unlock arround line

res = RfcUTF8ToSAPUC((RFC_BYTE*)utf8str, utf8len, retval, &retval_num_chrs, sapuclen, err);

make errors go away and all threads do the conversion successfully

isaias_freitas
Advisor
Advisor
0 Kudos

Nice!

Former Member
0 Kudos

Yes, it is nice, actually.

Though, I am dissapointed that the sdk does not support multi threading and - as it looks like - the cause is just a character set conversion function.

Would it be a good idea to implement my own thread-safe conversion functions? Or maybe there is an already implemented alternative solution?

I would appreciate an expert's opinion about that...

isaias_freitas
Advisor
Advisor
0 Kudos

Hello Loannis,

The RFC SDK should be thread-safe.

I contacted SAP Development Support and they will look into it.

For now, the best solution is that you keep your mutex lock.

Regards,

Isaías

Former Member
0 Kudos

So, I was wrong. The same problem still occurs.

But now i created a sample application to reproduce the issue:

#define SAPwithUNICODE

#define NUM_THREADS 3

#include <pthread.h>

#include <sapnwrfc.h>

RFC_RC utf8_to_sapuc(char *utf8str, unsigned int utf8len, SAP_UC **sapuc, unsigned int *sapuclen, RFC_ERROR_INFO *err)

{

    unsigned int retval_num_chrs = 0;

    SAP_UC *retval = NULL;

    RFC_RC res;

    /* let the conversion function decide the length of the needed buffer */

try_again:

    res = RfcUTF8ToSAPUC((RFC_BYTE*)utf8str, utf8len, retval, &retval_num_chrs, sapuclen, err);

    switch (res)

    {

        case RFC_BUFFER_TOO_SMALL:

            /** From function definition documentation:

             *

             * If the given buffer turns out to be too small (return code RFC_BUFFER_TOO_SMALL), it will be filled

             * with the required buffer size that would be necessary to convert the given input data.

             */

            /* re-allocate memory */

            if (NULL != retval) {

                retval = realloc(retval, retval_num_chrs * sizeof(SAP_UC));

            }

            else { /* first-time allocation */

                retval = malloc(retval_num_chrs * sizeof(SAP_UC));

            }

       

            memset(retval, 0, retval_num_chrs * sizeof(SAP_UC));

            goto try_again;

        case RFC_OK:

            *sapuc = retval;

            break;

        default:

            if (NULL != retval) {

                free(retval);

            }

    }

   

    return res;

}

void *threadFunction(void *threadId)

{

    const char *strU8 = "some unicode text: Δείγμα κειμένου"; /* Greek words */

    unsigned int strU8len = strlen(strU8); /* length of strU8 in bytes */

    SAP_UC *strU16;

    unsigned int strU16len;

    RFC_ERROR_INFO err;

    if (RFC_OK == utf8_to_sapuc((char*)strU8, strU8len, &strU16, &strU16len, &err)) {

        printfU16(cU("Converted text: %s\n"), strU16);

        free(strU16);

    }

    else {

        printfU(cU("Could not convert to SAP_UC [%s # %s]\n"), err.key, err.message);

    }

    pthread_exit(NULL);

    return NULL;

}

int main(int argc, char *argv[])

{

    pthread_t threads[NUM_THREADS];

    int rc;

    long t;

    void *status;

    for (t = 0; t < NUM_THREADS; t++)

    {

        rc = pthread_create(&threads[t], NULL, threadFunction, (void*)t);

        if (rc) {

            printf("pthread_created failed [%d]\n", rc); exit(1);

        }

    }

   

    for (t = 0; t < NUM_THREADS; t++) {

        rc = pthread_join(threads[t], &status);

    }

    exit(0);

}

Here's the output when running the above code under windows (x64):

Could not convert to SAP_UC [RFC_CONVERSION_FAILURE # cannot convert from codepage 4110to codepage 4103]

Could not convert to SAP_UC [RFC_CONVERSION_FAILURE # cannot convert from codepage 4110to codepage 4103]

Converted text: some unicode text: Δείγμα κειμένου

It seems like when more than 1 threads are concurrently accessing the conversion function, only one conversion will be successful.

Is this a normal behavior of the library? Do I have to lock access to conversion (and maybe all Rfc*) functions?

Thanks!