Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

vipconnectwait.c

Go to the documentation of this file.
00001 /********************************************************
00002  * Myricom VI-GM  networking software and documentation *
00003  * Copyright (c) 2001 by Myricom, Inc.                  *
00004  * All rights reserved.                                 *
00005  * See the file `COPYING' for copyright notice.         *
00006  ********************************************************/
00007 
00014 #include <stdlib.h>
00015 #include <string.h>
00016 
00017 #include "vipl_priv.h"
00018 
00019 
00071 VIP_ENTRY_POINT VIP_RETURN
00072 VipConnectWait (VIP_NIC_HANDLE NicHandle,
00073                 VIP_NET_ADDRESS * LocalAddr,
00074                 VIP_ULONG Timeout,
00075                 VIP_NET_ADDRESS * RemoteAddr,
00076                 VIP_VI_ATTRIBUTES * RemoteViAttribs,
00077                 VIP_CONN_HANDLE * ConnHandle)
00078 {
00079   VIP_GM *vip_gm_ptr;
00080   VIP_NIC *vip_nic_ptr;
00081   VIP_CONN *vip_conn_ptr;
00082   VIP_RETURN vip_status;
00083   VIP_DEBUG_LABEL (("VipConnectWait"));
00084 
00085 
00086   if (LocalAddr == NULL)
00087     {
00088       VIP_DEBUG (("LocalAddr is NULL"));
00089       return VIP_INVALID_PARAMETER;
00090     }
00091 
00092   if (RemoteAddr == NULL)
00093     {
00094       VIP_DEBUG (("RemoteAddr is NULL"));
00095       return VIP_INVALID_PARAMETER;
00096     }
00097 
00098   if (RemoteViAttribs == NULL)
00099     {
00100       VIP_DEBUG (("RemoteViAttribs is NULL"));
00101       return VIP_INVALID_PARAMETER;
00102     }
00103 
00104   if (ConnHandle == NULL)
00105     {
00106       VIP_DEBUG (("ConnHandle is NULL"));
00107       return VIP_INVALID_PARAMETER;
00108     }
00109 
00110   /* check local address (host part) */
00111   if (LocalAddr->HostAddressLen != VI_GM_MAC_ADDRESS_LEN)
00112     {
00113       VIP_DEBUG (("Host Address Length is invalid (should be %d)",
00114                   VI_GM_MAC_ADDRESS_LEN));
00115       return VIP_INVALID_PARAMETER;
00116     }
00117 
00118   /* check local address (discriminator part) */
00119   if (LocalAddr->DiscriminatorLen > VI_GM_MAX_DISCRIMINATOR_LEN)
00120     {
00121       VIP_DEBUG (("Discriminator Length is too large (max=%d)",
00122                   VI_GM_MAX_DISCRIMINATOR_LEN));
00123       return VIP_INVALID_PARAMETER;
00124     }
00125 
00126   /* check timeout */
00127   if (Timeout == 0)
00128     {
00129       VIP_DEBUG (("Timeout 0 immediat return"));
00130       return VIP_TIMEOUT;
00131     }
00132 
00133   /* check nic handle */
00134   vip_nic_ptr = (VIP_NIC *) NicHandle;
00135   if (VIP_INVALID_NIC_HANDLE (vip_nic_ptr))
00136     {
00137       VIP_DEBUG (("Invalid NIC handle"));
00138       return VIP_INVALID_PARAMETER;
00139     }
00140 
00141   vip_gm_ptr = vip_nic_ptr->vip_gm_ptr;
00142   VIP_MUTEX_LOCK (&(vip_gm_ptr->lock));
00143   VIP_PROGRESSION (vip_gm_ptr);
00144   VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00145 
00146   /* check NIC address consistency */
00147   if (memcmp (vip_gm_ptr->mac_address, LocalAddr->HostAddress,
00148               LocalAddr->HostAddressLen) != 0)
00149     {
00150       VIP_DEBUG (("Host Address does not match NIC id"));
00151       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00152       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00153       return VIP_INVALID_PARAMETER;
00154     }
00155 
00156   /* allocate conn handle */
00157   vip_conn_ptr =
00158     (VIP_CONN *) vip_allocate_handle (&(vip_nic_ptr->vip_conn_set));
00159   if (vip_conn_ptr == NULL)
00160     {
00161       VIP_DEBUG (("VIP_CONN alloc failed"));
00162       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00163       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00164       return VIP_ERROR_RESOURCE;
00165     }
00166 
00167   vip_conn_ptr->locale_disc_len = LocalAddr->DiscriminatorLen;
00168   memcpy (vip_conn_ptr->locale_net_addr, LocalAddr->HostAddress,
00169           VI_GM_MAC_ADDRESS_LEN + LocalAddr->DiscriminatorLen);
00170   vip_conn_ptr->type = VIP_CONN_TYPE_SERVER;
00171   vip_conn_ptr->status = VIP_NOT_DONE;
00172   VIP_EVENT_INIT (&(vip_conn_ptr->event));
00173   vip_conn_ptr->vip_vi_ptr = NULL;
00174   vip_conn_ptr->next_waiting_conn_ptr = NULL;
00175 
00176   /* insert connection in the waiting list */
00177   if (vip_gm_ptr->head_waiting_conn_ptr == NULL)
00178     {
00179       VIP_ASSERT (vip_gm_ptr->tail_waiting_conn_ptr == NULL);
00180       vip_gm_ptr->head_waiting_conn_ptr = vip_conn_ptr;
00181       vip_gm_ptr->tail_waiting_conn_ptr = vip_conn_ptr;
00182       vip_conn_ptr->prev_waiting_conn_ptr = NULL;
00183     }
00184   else
00185     {
00186       VIP_ASSERT (vip_gm_ptr->tail_waiting_conn_ptr != NULL);
00187       vip_gm_ptr->tail_waiting_conn_ptr->next_waiting_conn_ptr = vip_conn_ptr;
00188       vip_conn_ptr->prev_waiting_conn_ptr = vip_gm_ptr->tail_waiting_conn_ptr;
00189       vip_gm_ptr->tail_waiting_conn_ptr = vip_conn_ptr;
00190     }
00191   vip_conn_ptr->waiting_list = VIP_TRUE;
00192 
00193   /* blocks */
00194   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00195   vip_status = vip_wait_for_notification (Timeout,
00196                                           (VIP_HANDLE *) vip_conn_ptr,
00197                                           &(vip_conn_ptr->event),
00198                                           vip_is_conn_notified, vip_conn_ptr);
00199   VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00200 
00201   /* check return code of blocking wait */
00202   switch (vip_status)
00203     {
00204     case VIP_SUCCESS:
00205       VIP_ASSERT (vip_conn_ptr->status == VIP_SUCCESS);
00206       RemoteAddr->HostAddressLen = VI_GM_MAC_ADDRESS_LEN;
00207       RemoteAddr->DiscriminatorLen = vip_conn_ptr->remote_disc_len;
00208       memcpy (RemoteAddr->HostAddress, vip_conn_ptr->remote_net_addr,
00209               VI_GM_MAC_ADDRESS_LEN + vip_conn_ptr->remote_disc_len);
00210       *RemoteViAttribs = vip_conn_ptr->remote_vi_attribs;
00211       *ConnHandle = (VIP_CONN_HANDLE) vip_conn_ptr;
00212       VIP_DEBUG (("Success"));
00213       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00214       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00215       return VIP_SUCCESS;
00216 
00217     case VIP_INVALID_PARAMETER:
00218       vip_remove_conn_waiting_list (vip_gm_ptr, vip_conn_ptr);
00219       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00220       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00221       return VIP_INVALID_PARAMETER;
00222 
00223     case VIP_TIMEOUT:
00224       /* timeout and no connection established */
00225       VIP_ASSERT (vip_conn_ptr->status == VIP_NOT_DONE);
00226       vip_remove_conn_waiting_list (vip_gm_ptr, vip_conn_ptr);
00227       vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00228                        (VIP_HANDLE *) vip_conn_ptr);
00229       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00230       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00231       *ConnHandle = NULL;
00232       return VIP_TIMEOUT;
00233 
00234     default:
00235       VIP_ABORT (("Blocking wait return code is invalid"));
00236     }
00237 
00238   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00239   VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00240   return vip_status;
00241 }
VI-GM-1.3 by Myricom © 1997-2006. Documentation generated on 20 May 2006 by doxygen 1.4.4.