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