on 06-28-2016 12:12 PM
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
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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...
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!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
85 | |
10 | |
10 | |
10 | |
7 | |
6 | |
6 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.