Whamcloud - gitweb
- landing of b_hd_cleanup_merge to HEAD.
[fs/lustre-release.git] / lnet / ulnds / socklnd / proclib.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (c) 2002 Cray Inc.
5  *  Copyright (c) 2003 Cluster File Systems, Inc.
6  *
7  *   This file is part of Lustre, http://www.lustre.org.
8  *
9  *   Lustre is free software; you can redistribute it and/or
10  *   modify it under the terms of version 2 of the GNU General Public
11  *   License as published by the Free Software Foundation.
12  *
13  *   Lustre is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with Lustre; if not, write to the Free Software
20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 /* lib.c:
24  *  This file provides the 'library' side for the process-based nals.
25  *  it is responsible for communication with the 'api' side and
26  *  providing service to the generic portals 'library'
27  *  implementation. 'library' might be better termed 'communication'
28  *  or 'kernel'.
29  */
30  
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <stdarg.h>
34 #include <unistd.h>
35 #include <procbridge.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <netdb.h>
39 #include <errno.h>
40 #include <timer.h>
41 #include <dispatch.h>
42
43 /* the following functions are stubs to satisfy the nal definition
44    without doing anything particularily useful*/
45
46 static int nal_dist(lib_nal_t *nal,
47                     ptl_nid_t nid,
48                     unsigned long *dist)
49 {
50     return 0;
51 }
52
53 static void check_stopping(void *z)
54 {
55     bridge b = z;
56     procbridge p = b->local;
57
58     if ((p->nal_flags & NAL_FLAG_STOPPING) == 0)
59             return;
60     
61     pthread_mutex_lock(&p->mutex);
62     p->nal_flags |= NAL_FLAG_STOPPED;
63     pthread_cond_broadcast(&p->cond);
64     pthread_mutex_unlock(&p->mutex);
65
66     pthread_exit(0);
67 }
68
69
70 /* Function:  nal_thread
71  * Arguments: z: an opaque reference to a nal control structure
72  *               allocated and partially populated by the api level code
73  * Returns: nothing, and only on error or explicit shutdown
74  *
75  *  This function is the entry point of the pthread initiated on 
76  *  the api side of the interface. This thread is used to handle
77  *  asynchronous delivery to the application.
78  * 
79  *  We define a limit macro to place a ceiling on limits
80  *   for syntactic convenience
81  */
82 extern int tcpnal_init(bridge);
83
84 nal_initialize nal_table[PTL_IFACE_MAX]={0,tcpnal_init,0};
85
86 void *nal_thread(void *z)
87 {
88     nal_init_args_t *args = (nal_init_args_t *) z;
89     bridge b = args->nia_bridge;
90     procbridge p=b->local;
91     int rc;
92     ptl_process_id_t process_id;
93     int nal_type;
94     
95     b->lib_nal=(lib_nal_t *)malloc(sizeof(lib_nal_t));
96     b->lib_nal->libnal_data=b;
97     b->lib_nal->libnal_map=NULL;
98     b->lib_nal->libnal_unmap=NULL;
99     b->lib_nal->libnal_dist=nal_dist;
100
101     nal_type = args->nia_nal_type;
102
103     /* Wierd, but this sets b->lib_nal->libnal_ni.ni_pid.{nid,pid}, which
104      * lib_init() is about to do from the process_id passed to it...*/
105     set_address(b,args->nia_requested_pid);
106
107     process_id = b->lib_nal->libnal_ni.ni_pid;
108     
109     if (nal_table[nal_type]) rc=(*nal_table[nal_type])(b);
110     /* initialize the generic 'library' level code */
111
112     rc = lib_init(b->lib_nal, args->nia_apinal, 
113                   process_id, 
114                   args->nia_requested_limits, 
115                   args->nia_actual_limits);
116
117     /*
118      * Whatever the initialization returned is passed back to the
119      * user level code for further interpretation.  We just exit if
120      * it is non-zero since something went wrong.
121      */
122     /* this should perform error checking */
123     pthread_mutex_lock(&p->mutex);
124     p->nal_flags |= (rc != PTL_OK) ? NAL_FLAG_STOPPED : NAL_FLAG_RUNNING;
125     pthread_cond_broadcast(&p->cond);
126     pthread_mutex_unlock(&p->mutex);
127
128     if (rc == PTL_OK) {
129         /* the thunk function is called each time the timer loop
130            performs an operation and returns to blocking mode. we
131            overload this function to inform the api side that
132            it may be interested in looking at the event queue */
133         register_thunk(check_stopping,b);
134         timer_loop();
135     }
136     return(0);
137 }