Пример #1
0
DLL_EXPORT
void FishHang_DeleteCriticalSection
(
    const char*  pszFileDeleting, // source file that's deleting it
    const int    nLineDeleting,   // line number of source file

    LPCRITICAL_SECTION lpCriticalSection   // address of critical section object
)
{
    FISH_THREAD*  pFISH_THREAD;
    FISH_LOCK*    pFISH_LOCK;

    FIXFILENAME(pszFileDeleting);

    LockFishHang();

    if (!GetThreadAndLockPtrs(&pFISH_THREAD,&pFISH_LOCK,lpCriticalSection))
        FishHangAbort(pszFileDeleting,nLineDeleting);

    if (!bFishHangAtExit && pFISH_LOCK->nLockedDepth)
    {
        logmsg(
            "\n** ERROR ** FISH_THREAD %8.8X "
            "deleting still-locked FISH_LOCK %8.8X!\n",
            (int)pFISH_THREAD,
            (int)pFISH_LOCK
            );

        if (pFISH_LOCK->pOwningThread != pFISH_THREAD)
        {
            logmsg(
                "** ERROR ** FISH_LOCK %8.8X "
                "owned by FISH_THREAD %8.8X!\n",
                (int)pFISH_LOCK,
                (int)pFISH_LOCK->pOwningThread
                );
        }

        logmsg("%s(%d)\n\n",pszFileDeleting,nLineDeleting);
        logmsg("%s\n",PrintFISH_THREAD(pFISH_THREAD));
        logmsg("%s\n",PrintFISH_LOCK(pFISH_LOCK));
    }

    RemoveListEntry(&pFISH_LOCK->LockListLink);
    if (pFISH_LOCK->ThreadLockListLink.Flink)
    {
        RemoveListEntry(&pFISH_LOCK->ThreadLockListLink);
    }
    free(pFISH_LOCK);

    UnlockFishHang();

    DeleteCriticalSection(lpCriticalSection);
}
Пример #2
0
DEVTHREADPARMS*  SelectDeviceThread()
{
    DEVTHREADPARMS*  pThreadParms;      // ptr to selected device thread
    LIST_ENTRY*      pListEntry;        // (work)

    pListEntry = ThreadListHeadListEntry.Flink;

    while (pListEntry != &ThreadListHeadListEntry)
    {
        pThreadParms = CONTAINING_RECORD(pListEntry,DEVTHREADPARMS,ThreadListLinkingListEntry);

        LockThreadParms(pThreadParms);      // (freeze moving target)

        if (pThreadParms->bThreadIsDead)
        {
            UnlockThreadParms(pThreadParms);
            RemoveThisThreadFromOurList(pThreadParms);
            pListEntry = ThreadListHeadListEntry.Flink;
            continue;
        }

        if (!IsEventSet(pThreadParms->hRequestQueuedEvent))
        {
            RemoveListEntry(pListEntry);
            InsertListTail(&ThreadListHeadListEntry,pListEntry);
            return pThreadParms;
        }

        UnlockThreadParms(pThreadParms);    // (can't use this one)

        pListEntry = pListEntry->Flink;
    }

    return NULL;    // (all of them are busy)
}
Пример #3
0
void  RemoveThisThreadFromOurList(DEVTHREADPARMS* pThreadParms)
{
    RemoveListEntry(&pThreadParms->ThreadListLinkingListEntry);
    MyCloseHandle(pThreadParms->hShutdownEvent);
    MyCloseHandle(pThreadParms->hRequestQueuedEvent);
    MyDeleteCriticalSection(&pThreadParms->IORequestListLock);
    free(pThreadParms);
    ios_devtnbr--;          // (track number of active device_thread)
}
Пример #4
0
DLL_EXPORT
BOOL FishHang_CloseHandle   // ** NOTE: only events for right now **
(
    const char*  pszFileClosed,   // source file that closed it
    const int    nLineClosed,     // line number of source file

    HANDLE  hEvent          // handle to event object
)
{
    FISH_THREAD*  pThisFISH_THREAD;
    FISH_EVENT*   pFISH_EVENT;
    LIST_ENTRY*   pListEntry;
    FISH_THREAD*  pWaitingFISH_THREAD;

    FIXFILENAME(pszFileClosed);

    LockFishHang();

    if (!GetThreadAndEventPtrs(&pThisFISH_THREAD,&pFISH_EVENT,hEvent))
        FishHangAbort(pszFileClosed,nLineClosed);

    pListEntry = ThreadsListHead.Flink;

    while (pListEntry != &ThreadsListHead)
    {
        pWaitingFISH_THREAD = CONTAINING_RECORD(pListEntry,FISH_THREAD,ThreadListLink);
        pListEntry = pListEntry->Flink;

        if (!pWaitingFISH_THREAD->bWaitingForEvent ||
            pWaitingFISH_THREAD->pWhatWaiting != pFISH_EVENT) continue;

        logmsg(
            "\n** ERROR ** %s(%d); FISH_THREAD %8.8X "
            "is closing FISH_EVENT %8.8X "
            "that FISH_THREAD %8.8X is still waiting on!\n",
            pszFileClosed,nLineClosed,(int)pThisFISH_THREAD,
            (int)pFISH_EVENT,
            (int)pWaitingFISH_THREAD
            );

        logmsg("\n%s\n%s\n%s\n",
            PrintFISH_THREAD(pThisFISH_THREAD),
            PrintFISH_EVENT(pFISH_EVENT),
            PrintFISH_THREAD(pWaitingFISH_THREAD)
            );

        FishHangAbort(pszFileClosed,nLineClosed);
    }

    RemoveListEntry(&pFISH_EVENT->EventsListLink);
    free(pFISH_EVENT);

    UnlockFishHang();

    return CloseHandle(hEvent);
}
Пример #5
0
/*-------------------------------------------------------------------*/
DLL_EXPORT int  hthread_destroy_rwlock( RWLOCK* plk, const char* location )
{
    int rc;
    ILOCK* ilk;
    UNREFERENCED( location );
    ilk = (ILOCK*) plk->ilk;
    rc = hthread_rwlock_destroy( &ilk->rwlock );
    LockLocksList();
    RemoveListEntry( &ilk->locklink );
    lockcount--;
    UnlockLocksList();
    free_aligned( ilk );
    plk->ilk = NULL;
    return rc;
}
Пример #6
0
DLL_EXPORT
void FishHang_ExitThread
(
    DWORD dwExitCode    // exit code for this thread
)
{
    FISH_THREAD*  pFISH_THREAD;
    LIST_ENTRY*   pListEntry;
    FISH_LOCK*    pFISH_LOCK;

    LockFishHang();

    if (!(pFISH_THREAD = FindFISH_THREAD(GetCurrentThreadId())))
    {
        UnlockFishHang();
        logmsg("** FishHang_ExitThread: FindFISH_THREAD failed!\n");
        if (bFishHangAtExit) _endthreadex(dwExitCode);
        exit(-1);
    }

    // "If a thread terminates while it has ownership of a critical
    // section, the state of the critical section is undefined."

    if (!bFishHangAtExit && !IsListEmpty(&pFISH_THREAD->ThreadLockListHead))
    {
        logmsg(
            "\n** ERROR ** FISH_THREAD %8.8X "
            "exiting with locks still owned!\n\n",
            (int)pFISH_THREAD);

        RemoveListEntry(&pFISH_THREAD->ThreadListLink);
        InsertListHead(&ThreadsListHead,&pFISH_THREAD->ThreadListLink);
        logmsg("%s\n",PrintFISH_THREAD(pFISH_THREAD));

        pListEntry = pFISH_THREAD->ThreadLockListHead.Flink;

        while (pListEntry != &pFISH_THREAD->ThreadLockListHead)
        {
            pFISH_LOCK = CONTAINING_RECORD(pListEntry,FISH_LOCK,ThreadLockListLink);
            pListEntry = pListEntry->Flink;
            logmsg("%s\n",PrintFISH_LOCK(pFISH_LOCK));
        }
    }

    UnlockFishHang();

    _endthreadex(dwExitCode);
}
Пример #7
0
DLL_EXPORT
void FishHang_LeaveCriticalSection
(
    const char*  pszFileReleasing,    // source file that attempted it
    const int    nLineReleasing,      // line number of source file

    LPCRITICAL_SECTION lpCriticalSection   // address of critical section object
)
{
    FISH_THREAD*  pFISH_THREAD;
    FISH_LOCK*    pFISH_LOCK;

    FIXFILENAME(pszFileReleasing);

    LockFishHang();

    if (!GetThreadAndLockPtrs(&pFISH_THREAD,&pFISH_LOCK,lpCriticalSection))
        FishHangAbort(pszFileReleasing,nLineReleasing);

    if (!bFishHangAtExit && pFISH_LOCK->pOwningThread != pFISH_THREAD)
    {
        logmsg(
            "\n** ERROR ** FISH_THREAD %8.8X "
            "releasing FISH_LOCK %8.8X "
            "owned by FISH_THREAD %8.8X!\n"
            "** Here's the culprit! --> %s(%d)\n",
            (int)pFISH_THREAD,
            (int)pFISH_LOCK,
            (int)pFISH_LOCK->pOwningThread,
            pszFileReleasing,nLineReleasing
            );

        RemoveListEntry(&pFISH_THREAD->ThreadListLink);
        InsertListHead(&ThreadsListHead,&pFISH_THREAD->ThreadListLink);
        PrintAllFISH_THREADs();

        if (pFISH_LOCK->pOwningThread)
        {
            RemoveListEntry(&pFISH_LOCK->ThreadLockListLink);
            InsertListHead(&pFISH_LOCK->pOwningThread->ThreadLockListHead,&pFISH_LOCK->ThreadLockListLink);
        }
        PrintAllFISH_LOCKs();
        FishHangAbort(pszFileReleasing,nLineReleasing);
    }
    else
    {
        pFISH_LOCK->nLockedDepth--;
    }

    if (pFISH_LOCK->nLockedDepth <= 0)
    {
        if (pFISH_LOCK->nLockedDepth < 0)
        {
            logmsg(
                "\n** ERROR ** FISH_THREAD %8.8X "
                "attempted to release FISH_LOCK %8.8X "
                "one too many times!?!\n"
                "** Here's the culprit! --> %s(%d)\n",
                (int)pFISH_THREAD,
                (int)pFISH_LOCK,
                pszFileReleasing,nLineReleasing
                );

            RemoveListEntry(&pFISH_THREAD->ThreadListLink);
            InsertListHead(&ThreadsListHead,&pFISH_THREAD->ThreadListLink);
            PrintAllFISH_THREADs();

            if (pFISH_LOCK->pOwningThread)
            {
                RemoveListEntry(&pFISH_LOCK->ThreadLockListLink);
                InsertListHead(&pFISH_LOCK->pOwningThread->ThreadLockListHead,&pFISH_LOCK->ThreadLockListLink);
            }
            PrintAllFISH_LOCKs();
            FishHangAbort(pszFileReleasing,nLineReleasing);
        }
        pFISH_LOCK->pOwningThread = NULL;
        RemoveListEntry(&pFISH_LOCK->ThreadLockListLink);
        InitializeListLink(&pFISH_LOCK->ThreadLockListLink);
    }

    UnlockFishHang();

    LeaveCriticalSection(lpCriticalSection);
}
Пример #8
0
/*-------------------------------------------------------------------*/
int unbind_device_ex (DEVBLK* dev, int forced)
{
    bind_struct* bs;

    logdebug("unbind_device(%4.4X)\n", dev->devnum);

    /* Error if device not bound */
    if (!(bs = dev->bs))
    {
        logmsg (_("HHCSD005E Device %4.4X not bound to any socket\n"),
            dev->devnum);
        return 0;   /* (failure) */
    }

    /* Is anyone still connected? */
    if (dev->fd != -1)
    {
        /* Yes. Should we forcibly disconnect them? */
        if (forced)
        {
            /* Yes. Then do so... */
            close_socket( dev->fd );
            dev->fd = -1;
            logmsg (_("HHCSD025I Client %s (%s) disconnected from device %4.4X (%s)\n"),
                dev->bs->clientip, dev->bs->clientname, dev->devnum, dev->bs->spec);
        }
        else
        {
            /* No. Then fail the request. */
            logmsg (_("HHCSD006E Client %s (%s) still connected to device %4.4X (%s)\n"),
                dev->bs->clientip, dev->bs->clientname, dev->devnum, dev->bs->spec);
            return 0;   /* (failure) */
        }
    }

    /* Remove the entry from our list */

    obtain_lock( &bind_lock );
    RemoveListEntry( &bs->bind_link );
    SIGNAL_SOCKDEV_THREAD();
    release_lock( &bind_lock );

    logmsg (_("HHCSD007I Device %4.4X unbound from socket %s\n"),
        dev->devnum, bs->spec);

    if (bs->sd != -1)
        close_socket (bs->sd);

    /* Unchain device and bind_struct from each another */

    dev->bs = NULL;
    bs->dev = NULL;

    /* Discard the entry */

    if ( bs->clientname ) free( bs->clientname );
    if ( bs->clientip   ) free( bs->clientip   );

    bs->clientname = NULL;
    bs->clientip   = NULL;

    free ( bs->spec );
    free ( bs );

    return 1;   /* (success) */
}
Пример #9
0
/*-------------------------------------------------------------------*/
int bind_device_ex (DEVBLK* dev, char* spec, ONCONNECT fn, void* arg )
{
    bind_struct* bs;
    int was_list_empty;

    if (!init_done) init_sockdev();

    if (sysblk.shutdown) return 0;

    logdebug("bind_device (%4.4X, %s)\n", dev->devnum, spec);

    /* Error if device already bound */
    if (dev->bs)
    {
        logmsg (_("HHCSD001E Device %4.4X already bound to socket %s\n"),
            dev->devnum, dev->bs->spec);
        return 0;   /* (failure) */
    }

    /* Create a new bind_struct entry */
    bs = malloc(sizeof(bind_struct));

    if (!bs)
    {
        logmsg (_("HHCSD002E bind_device malloc() failed for device %4.4X\n"),
            dev->devnum);
        return 0;   /* (failure) */
    }

    memset(bs,0,sizeof(bind_struct));

    bs->fn  = fn;
    bs->arg = arg;

    if (!(bs->spec = strdup(spec)))
    {
        logmsg (_("HHCSD003E bind_device strdup() failed for device %4.4X\n"),
            dev->devnum);
        free (bs);
        return 0;   /* (failure) */
    }

    /* Create a listening socket */
    if (bs->spec[0] == '/') bs->sd = unix_socket (bs->spec);
    else                    bs->sd = inet_socket (bs->spec);
    if (bs->sd == -1)
    {
        /* (error message already issued) */
        free( bs->spec );
        free( bs );
        return 0; /* (failure) */
    }

    /* Chain device and bind_struct to each other */
    dev->bs = bs;
    bs->dev = dev;

    /* Add the new entry to our list of bound devices
       and create the socket thread that will listen
       for connections (if it doesn't already exist) */

    obtain_lock( &bind_lock );

    was_list_empty = IsListEmpty( &bind_head );

    InsertListTail( &bind_head, &bs->bind_link );

    if ( was_list_empty )
    {
        if ( create_thread( &sysblk.socktid, JOINABLE,
                            socket_thread, NULL, "socket_thread" ) )
            {
                logmsg( _( "HHCSD023E Cannot create socketdevice thread: errno=%d: %s\n" ),
                        errno, strerror( errno ) );
                RemoveListEntry( &bs->bind_link );
                close_socket(bs->sd);
                free( bs->spec );
                free( bs );
                release_lock( &bind_lock );
                return 0; /* (failure) */
            }
    }

    SIGNAL_SOCKDEV_THREAD();

    release_lock( &bind_lock );

    logmsg (_("HHCSD004I Device %4.4X bound to socket %s\n"),
        dev->devnum, dev->bs->spec);

    return 1;   /* (success) */
}
Пример #10
0
/*-------------------------------------------------------------------*/
int unbind_device_ex (DEVBLK* dev, int forced)
{
    bind_struct* bs;

    logdebug("unbind_device(%4.4X)\n", dev->devnum);

    /* Error if device not bound */
    if (!(bs = dev->bs))
    {
        WRMSG (HHC01043, "E", SSID_TO_LCSS(dev->ssid), dev->devnum);
        return 0;   /* (failure) */
    }

    /* Is anyone still connected? */
    if (dev->fd != -1)
    {
        /* Yes. Should we forcibly disconnect them? */
        if (forced)
        {
            /* Yes. Then do so... */
            close_socket( dev->fd );
            dev->fd = -1;
            WRMSG (HHC01044, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->clientip,
                   dev->bs->clientname, dev->bs->spec);
        }
        else
        {
            /* No. Then fail the request. */
            WRMSG (HHC01045, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->clientip,
                   dev->bs->clientname, dev->bs->spec);
            return 0;   /* (failure) */
        }
    }

    /* Remove the entry from our list */

    obtain_lock( &bind_lock );
    RemoveListEntry( &bs->bind_link );
    SIGNAL_SOCKDEV_THREAD();
    release_lock( &bind_lock );

    WRMSG (HHC01046, "I",SSID_TO_LCSS(dev->ssid), dev->devnum, bs->spec);

    if (bs->sd != -1)
        close_socket (bs->sd);

    /* Unchain device and bind_struct from each another */

    dev->bs = NULL;
    bs->dev = NULL;

    /* Discard the entry */

    if ( bs->clientname ) free( bs->clientname );
    if ( bs->clientip   ) free( bs->clientip   );

    bs->clientname = NULL;
    bs->clientip   = NULL;

    free ( bs->spec );
    free ( bs );

    return 1;   /* (success) */
}
Пример #11
0
/*-------------------------------------------------------------------*/
int bind_device_ex (DEVBLK* dev, char* spec, ONCONNECT fn, void* arg )
{
    bind_struct* bs;
    int was_list_empty;
    int rc;

    if (!init_done) init_sockdev();

    if (sysblk.shutdown) return 0;

    logdebug("bind_device (%4.4X, %s)\n", dev->devnum, spec);

    /* Error if device already bound */
    if (dev->bs)
    {
        WRMSG (HHC01041, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->spec);
        return 0;   /* (failure) */
    }

    /* Create a new bind_struct entry */
    bs = malloc(sizeof(bind_struct));

    if (!bs)
    {
        char buf[40];
        MSGBUF( buf, "malloc(%d)", (int)sizeof(bind_struct));
        WRMSG (HHC01000, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, buf, strerror(errno));
        return 0;   /* (failure) */
    }

    memset(bs, 0, sizeof(bind_struct));

    bs->fn  = fn;
    bs->arg = arg;

    if (!(bs->spec = strdup(spec)))
    {
        WRMSG (HHC01000, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "strdup()", strerror(errno) );
        free (bs);
        return 0;   /* (failure) */
    }

    /* Create a listening socket */
    if (bs->spec[0] == '/') bs->sd = unix_socket (bs->spec);
    else                    bs->sd = inet_socket (bs->spec);
    if (bs->sd == -1)
    {
        /* (error message already issued) */
        free( bs->spec );
        free( bs );
        return 0; /* (failure) */
    }

    /* Chain device and bind_struct to each other */
    dev->bs = bs;
    bs->dev = dev;

    /* Add the new entry to our list of bound devices
       and create the socket thread that will listen
       for connections (if it doesn't already exist) */

    obtain_lock( &bind_lock );

    was_list_empty = IsListEmpty( &bind_head );

    InsertListTail( &bind_head, &bs->bind_link );

    if ( was_list_empty )
    {
        rc = create_thread( &sysblk.socktid, JOINABLE,
                            socket_thread, NULL, "socket_thread" );
        if (rc)
        {
            WRMSG(HHC00102, "E", strerror( rc ) );
            RemoveListEntry( &bs->bind_link );
            close_socket(bs->sd);
            free( bs->spec );
            free( bs );
            release_lock( &bind_lock );
            return 0; /* (failure) */
        }
    }

    SIGNAL_SOCKDEV_THREAD();

    release_lock( &bind_lock );

    WRMSG (HHC01042, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->spec);

    return 1;   /* (success) */
}