summaryrefslogtreecommitdiffstats
path: root/private/ntos/nbt/vxd/ctimer.c
blob: 29cca31794f5cb528a64313b9deecacb27fa7bfd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/**********************************************************************/
/**                       Microsoft Windows                          **/
/**                Copyright(c) Microsoft Corp., 1993                **/
/**********************************************************************/

/*

    Timer.c

    This module checks for active sessions on all adapters for send/receive
    NCBs that have timed out.

    A single timer is used for all adapters.

    If a send times out, then the session will be aborted.

    FILE HISTORY:
        Johnl   23-Sep-1993     Created

*/

#include <nbtprocs.h>
#include <ctemacro.h>

CTETimer TimeoutTimer ;

/*******************************************************************

    NAME:       CheckForTimedoutNCBs

    SYNOPSIS:   Traverses list of all send/receive NCBs checking for
                any that have reached their timeout point every half
                second.

    ENTRY:      pEvent - Not used
                pCont  - Not used

    RETURNS:    TRUE if the timer successfully started, FALSE otherwise

    NOTES:      This is a self perpetuating function, each time it is called,
                it schedules the timer again for a 1/2 second later to
                call itself.

                To get it going, it should be called once during
                initialization

    HISTORY:
        Johnl   23-Sep-1993     Created

********************************************************************/

BOOL CheckForTimedoutNCBs( CTEEvent *pCTEEvent, PVOID pCont )
{
    tNAMEADDR         * pNameAddr ;
    tCLIENTELE        * pClientEle ;
    tCONNECTELE       * pConnectEle ;
    LIST_ENTRY        * pEntry ;
    LIST_ENTRY        * pEntryClient ;
    LIST_ENTRY        * pEntryConn ;
    LIST_ENTRY        * pEntryRcv ;

    //
    // Look for Receive NCBs first
    //
    for ( pEntry = NbtConfig.AddressHead.Flink ;
          pEntry != &NbtConfig.AddressHead ;
          pEntry = pEntry->Flink )
    {
        PLIST_ENTRY   pEntryClient ;
        tADDRESSELE * pAddrEle = CONTAINING_RECORD( pEntry,
                                                    tADDRESSELE,
                                                    Linkage ) ;
        ASSERT( pAddrEle->Verify == NBT_VERIFY_ADDRESS ) ;

        for ( pEntryClient = pAddrEle->ClientHead.Flink ;
              pEntryClient != &pAddrEle->ClientHead ;
              pEntryClient = pEntryClient->Flink )
        {
            tCLIENTELE * pClientEle = CONTAINING_RECORD( pEntryClient,
                                                         tCLIENTELE,
                                                         Linkage ) ;
            PLIST_ENTRY   pEntryConn ;
            ASSERT( pClientEle->Verify == NBT_VERIFY_CLIENT ||
                    pClientEle->Verify == NBT_VERIFY_CLIENT_DOWN ) ;

            for ( pEntryConn = pClientEle->ConnectActive.Flink ;
                  pEntryConn != &pClientEle->ConnectActive ;
                  pEntryConn = pEntryConn->Flink )
            {
                PRCV_CONTEXT prcvCont ;
                pConnectEle = CONTAINING_RECORD( pEntryConn,
                                                 tCONNECTELE,
                                                 Linkage ) ;
                ASSERT( pConnectEle->Verify == NBT_VERIFY_CONNECTION ||
                        pConnectEle->Verify == NBT_VERIFY_CONNECTION_DOWN ) ;

                if ( pConnectEle->RTO == NCB_INFINITE_TIME_OUT ||
                     pConnectEle->state != NBT_SESSION_UP      ||
                     IsListEmpty( &pConnectEle->RcvHead )        )
                {
                    continue ;
                }

                //
                //  Note that we only check the first receive buffer because
                //  the timeout is for the next receive indication (and not
                //  how long this NCB has been waiting).
                //
                pEntryRcv = pConnectEle->RcvHead.Flink ;
                prcvCont = CONTAINING_RECORD( pEntryRcv, RCV_CONTEXT, ListEntry ) ;
                ASSERT( prcvCont->Signature == RCVCONT_SIGN ) ;

                if ( prcvCont->RTO == NCB_TIMED_OUT )
                {
                    RemoveEntryList( &prcvCont->ListEntry ) ;
                    CTEIoComplete( prcvCont->pNCB, STATUS_TIMEOUT, 0 ) ;
                }
                else
                {
                    prcvCont->RTO-- ;
                }
            } // ConnectActive
        } // Client
    } // Address

    //
    //  Now look for Send NCB time outs.  Only connections that specified
    //  a timeout will be put on this list.
    //
    for ( pEntry = NbtConfig.SendTimeoutHead.Flink ;
          pEntry != &NbtConfig.SendTimeoutHead ;
        )
    {
        PSEND_CONTEXT pSendCont ;

        pSendCont = CONTAINING_RECORD( pEntry, SEND_CONTEXT, ListEntry ) ;
        pEntry = pEntry->Flink ;    // get the next one

        pSendCont->STO-- ;
        if ( pSendCont->STO == NCB_TIMED_OUT )
        {
            //
            //  Assumes pSendCont is stored in ncb_reserve field of NCB
            //  This will remove it from the timeout list also.
            //
            CTEIoComplete( CONTAINING_RECORD( pSendCont, NCB, ncb_reserve ),
                           STATUS_TIMEOUT,
                           0 ) ;
            // the above CTEIoComplete will trigger events from the transport
            // which could modify the SendTimeout list before we reach this
            // point.  Best just to wait until things clear up.
            break;
        }
    }

    //
    //  Restart the timer for a half second from now
    //
    CTEInitTimer( &TimeoutTimer ) ;
    return !!CTEStartTimer( &TimeoutTimer, 500, CheckForTimedoutNCBs, NULL ) ;
}


/*******************************************************************

    NAME:       StartRefreshTimer

    SYNOPSIS:   Start the refresh timer
                This function was necessary because of this scenario:
                  No node type was defined in registry, so we defaulted to
                  BNODE and didn't start refresh timer.
                  Now, while we are still coming up, dhcp tells us we are
                  MSNODE.  Shouldn't we start the refresh timer?
                That's why this function.

    HISTORY:
        Koti    9-Jun-1994     Created

********************************************************************/

NTSTATUS StartRefreshTimer( VOID )
{

    NTSTATUS status = STATUS_SUCCESS;
    tTIMERQENTRY        *pTimerEntry;

    //
    // make sure it's not bnode, and that timer really needs to be started
    //
    if (!(NodeType & BNODE) && (!NbtConfig.pRefreshTimer))
    {

        // the initial refresh rate until we can contact the name server
        NbtConfig.MinimumTtl = NBT_INITIAL_REFRESH_TTL;
        NbtConfig.sTimeoutCount = 0;

        status = StartTimer(
                NbtConfig.InitialRefreshTimeout,
                NULL,            // context value
                NULL,            // context2 value
                RefreshTimeout,
                NULL,
                NULL,
                0,
                &pTimerEntry);

        if ( !NT_SUCCESS( status ) )
            return status ;

        NbtConfig.pRefreshTimer = pTimerEntry;
    }

    return(STATUS_SUCCESS);
}


#ifdef CHICAGO

/*******************************************************************

    NAME:       StopTimeoutTimer

    SYNOPSIS:   Stops the timer that was set in CheckForTimedoutNCBs.
                This is needed only for Chicago which can dynamically
                unload vnbt.

    HISTORY:
        Koti    23-May-1994     Created

********************************************************************/

VOID StopTimeoutTimer( VOID )
{
    CTEStopTimer( &TimeoutTimer );
}

#endif