svn commit: branches/uClibc-nptl/libc/misc/dirent
Carmelo AMOROSO
carmelo.amoroso at st.com
Thu May 15 10:13:34 UTC 2008
Mike Frysinger wrote:
> On Thursday 15 May 2008, Carmelo AMOROSO wrote:
>
>> Mike Frysinger wrote:
>>
>>> On Wednesday 05 December 2007, carmelo at uclibc.org wrote:
>>>
>>>> Author: carmelo
>>>> Date: 2007-12-05 09:25:08 -0800 (Wed, 05 Dec 2007)
>>>> New Revision: 20626
>>>>
>>>> Log:
>>>> Fix opendir problem when statically linked due to a missing
>>>> initialization of the mutex field within DIR struct.
>>>> When linked dynamically instead, __pthread_mutex_init will
>>>> initialize the mutex itself. Without this fix, any call to
>>>> readdir will stuck forever trying to acquire the mutex.
>>>>
>>> sorry, but i dont follow. we call __pthread_mutex_init() on the dd_lock
>>> member of the dirent structure which should initialize the mutex just
>>> fine. you cant assume that zeroing the structure is the same as
>>> initializing the mutex. that is why we have these initializer functions
>>> in the first place. are you suggesting that the __pthread_mutex_init()
>>> function is not doing its job ?
>>>
>> yes exactly... but only if statically linked. I suspect that in this
>> case the __pthread_mutex_init is a nop...
>> likely due to weak aliasing... however, glibc does exactly the same call
>> to memset
>> and it uses
>>
>> #ifndef NOT_IN_libc
>> __libc_lock_init (dirp->lock);
>> #endif
>>
>> instead of __pthread_mutex_init(&(ptr->dd_lock), NULL);
>>
>
> can you provide a test case ? i'd like to fix the real problem ... adding a
> memset() just ignores the larger issue with every function that does
> something similar.
> -mike
>
Hi,
below there is the test used by an our customer that reported the error.
You can simplify it as you like.
Anyway, regarding this issue, I was thinking in the past to review the
use of pthread dor locking
within the libc and use instead something like glibc (libc_lock)... any
comments about this ?
Carmelo
sh4-linux-uclibc-gcc -g -o test test.c -lpthread -static
============================ source code =============
/* test.c for opendir and readdir */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <errno.h>
#include <dirent.h>
#define MAX_FILE_LENGTH 1024
void printdir(char *dir);
void readFile(const char *fileName);
void *jvmCommunication(void *ptr);
#define DIRTOOPEN "/var/java/appdb/"
int main(void)
{
printf("test start\n");
// printdir(DIRTOOPEN);
printf("before readfile\n");
readFile("/var/tvst.inf");
printf("after readfile.\n");
fflush(stdout);
printdir(DIRTOOPEN);
pthread_t t;
pthread_create(&t, NULL, jvmCommunication, NULL);
printf("after pthread_create.\n");
// printdir(DIRTOOPEN);
return 0;
}
void printdir(char *dir)
{
DIR *pDir = NULL;
struct dirent *ptEntry = NULL;
printf("before opendir.(%s)\n",dir);
fflush(stdout);
if (NULL == (pDir = opendir(dir))) // open failed
{
printf("cann't open %s.\n", dir);
return;
}
printf("after opendir.and before readdir.\n");
fflush(stdout);
printf("it will be hang in here ..\n");
while ((ptEntry = readdir(pDir)) != NULL)
{
printf("DIR:");
printf("%s\n", ptEntry->d_name);
}
printf("after readdir.and before closedir.\n");
fflush(stdout);
if (pDir != NULL)
{
closedir(pDir);
}
printf("after closedir.\n");
fflush(stdout);
return;
}
void readFile(const char *flName)
{
FILE * flHandl = NULL;
unsigned char ptChrUtf[MAX_FILE_LENGTH];
short ptChrUnicode[MAX_FILE_LENGTH];
memset(ptChrUtf, 0, MAX_FILE_LENGTH);
memset(ptChrUnicode, 0, MAX_FILE_LENGTH * sizeof(short));
flHandl = fopen(flName, "rb");
printf("after open\n");
if(flHandl == NULL) //´ò¿ªÎļþʧ°Ü
{
return;
}
fread(ptChrUtf, sizeof(char), MAX_FILE_LENGTH, flHandl);
printf("fread = %s\n", ptChrUtf);
#if 1
printf("if remove fclose() in here , there will be no hang \n");
fclose(flHandl); //if removed it. there will be no hang
#endif
printf("after fclose!\n");
return;
}
void *jvmCommunication(void *ptr)
{
while(1)
{
sleep(1);
printf("running ..!\n");
}
}
More information about the uClibc
mailing list