Example #1
0
static void mylock(pthread_mutex_t *mutex, int increment)
{
    volatile int *cnt = (int *) mutex;
    while(1)
    {
retry:
        if(*cnt == 0)
        {   // try to lock the counter
            (*cnt) += increment;
            if(*cnt > 1)
            {
                (*cnt) -= increment;
                goto retry; // another process also wanted to lock the counter
            }
            return;       // now we can do it
        }
        rlwthread_sleep(1);
    }
}
Example #2
0
int rlSocket::connect()
{
  int option;
  int ret;
#ifdef __VMS
  size_t    socklen = sizeof(struct sockaddr);
#else
  socklen_t socklen = sizeof(struct sockaddr);
#endif
  struct sockaddr_in     localAddr;
  struct sockaddr_in     remoteAddr;
  struct hostent        *host;
  struct in_addr         RemoteIpAddress;
#ifdef AF_INET6_IS_AVAILABLE
  struct addrinfo        hints0, hints1;
  struct addrinfo       *res, *ressave;
  int n;
  char portstr[32];
#endif

  if(port <= 0)       return PORT_ERR;
  if(port >= 256*256) return PORT_ERR;
  if(active == 0)
  { // accept calls
    s = -1;
    if(rl_ipversion == 4)
    {
      if(first == 1)
      {
        // create a socket
        os = socket(AF_INET,SOCK_STREAM,0);
        if(os == -1) return SOCKET_ERR;
        // set socket options 
#ifdef __VMS
        option = 1;
        if(setsockopt(os,SOL_SOCKET,SO_KEEPALIVE,&option,sizeof(option)) < 0)
        {
          return SETSOCKOPT_ERR;
        }
#endif
        option = 1;
#ifdef RLWIN32
        setsockopt(os,SOL_SOCKET,SO_REUSEADDR,(const char *) &option,sizeof(option));
#else
        setsockopt(os,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option));
#endif
        // Bind our server to the agreed upon port number.
        memset(&localAddr,0,sizeof(localAddr));
        localAddr.sin_port = htons((short) port);
        localAddr.sin_family = AF_INET;
bind:
        ret = bind(os, (struct sockaddr *) &localAddr, sizeof(localAddr));
        if(ret == -1)
        {
          rlwthread_sleep(1000);
          goto bind;
        }
        // Prepare to accept client connections.  Allow up to 5 pending 
        // connections.                                            
        ret = listen(os, 5);
        if(ret == -1) return LISTEN_ERR;
      }
      first = 0;

      // accept connections
      s = accept(os, (struct sockaddr *) &sockaddr[0], &socklen);
      if(s == -1) return ACCEPT_ERR;
    }
    else if(rl_ipversion == 6)
    {
#ifdef AF_INET6_IS_AVAILABLE
      if(first == 1)
      {
        memset(&hints0,0,sizeof(hints0));
        hints0.ai_flags = AI_PASSIVE;
        //hints0.ai_family = AF_UNSPEC;
        hints0.ai_family = AF_INET6;
        hints0.ai_socktype = SOCK_STREAM;
        sprintf(portstr,"%d",port);
        //::printf("server getaddrinfo(%s,%s)\n", adr, portstr);
        n = getaddrinfo(adr, portstr, &hints0, &res);
        if(n != 0)
        {
#ifndef RLWIN32
          ::printf("rlSocket:tcp_listen error for %s port=%s : %s\n", adr, portstr, gai_strerror(n));
#endif
          return -1;
        }
        //::printf("done\n");
        ressave = res;
bindv6:
        do
        {
          os = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
          if(os < 0)                                            continue; // error, try next one
#ifdef __VMS
          option = 1;
          if(setsockopt(os,SOL_SOCKET,SO_KEEPALIVE,&option,sizeof(option)) < 0)
          {
            return SETSOCKOPT_ERR;
          }
#endif
          option = 1;
#ifdef RLWIN32
          setsockopt(os,SOL_SOCKET,SO_REUSEADDR,(const char *) &option,sizeof(option));
#else
          setsockopt(os,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option));
#endif
          if(bind(os, res->ai_addr, res->ai_addrlen) == 0)      break;    // success
          s = os;
          disconnect();                                                   // bind error, close and try next one
        }
        while((res = res->ai_next) != NULL);
        if(res == NULL)                                                   // errno from final socket() or bind()
        {
          ::printf("warning: could not bind to port=%d\n", port);
          rlwthread_sleep(1000);
          goto bindv6;
        }
        // Prepare to accept client connections.  Allow up to 5 pending 
        // connections
        ret = listen(os, 5);
        freeaddrinfo(ressave);
        if(ret == -1) return LISTEN_ERR;
      }
      first = 0;
      // accept connections
      s = accept(os, (struct sockaddr *) &sockaddr[0], &socklen);
      if(s == -1) return ACCEPT_ERR;
#else
      ::printf("rlSocket:ERROR IPV6 not available on this platform\n");
#endif
    }
    else
    {
      ::printf("rlSocket:ERROR: rl_ipversion=%d not known\n", rl_ipversion);
    }
  } // end active == 0 
  else if(active == 1)
  {
    disconnect();
    //::printf("debug: adr=%s port=%d\n",adr,port);
    s = -1;
    if(rl_ipversion == 4)
    {
      os = socket(AF_INET,SOCK_STREAM,0);
      if(os == -1) return SOCKET_ERR;
      s = os;

      //::printf("debug: gethostbyname\n");
      // fill destblk structure 
      host = gethostbyname(adr);
      if(host == NULL)
      {
        // See if the host is specified in "dot address" form
        RemoteIpAddress.s_addr = inet_addr(adr);
        if(RemoteIpAddress.s_addr == INADDR_NONE)
        {
          s = -1;
          return INET_ADDR_ERR; // -1
        }
      }
      else
      {
        memcpy(&RemoteIpAddress,host->h_addr,host->h_length);
      }

      memset(&remoteAddr,0,sizeof(remoteAddr));
      remoteAddr.sin_family = AF_INET;
      remoteAddr.sin_port = htons((short) port);
      remoteAddr.sin_addr = RemoteIpAddress;

      //::printf("debug: connect\n");
      ret = ::connect(s, (struct sockaddr *) &remoteAddr, sizeof(remoteAddr));
      //::printf("debug: connect ret=%d\n",ret);
      if(ret == -1) 
      {
        disconnect(); // close s = os
        return CONNECT_ERR;
      }
    }
    else if(rl_ipversion == 6)
    {
#ifdef AF_INET6_IS_AVAILABLE
      sprintf(portstr,"%d",port);
      memset(&hints1, 0, sizeof(hints1));
      hints1.ai_family = AF_UNSPEC;
      hints1.ai_socktype = SOCK_STREAM;
      n = getaddrinfo(adr, portstr, &hints1, &res);
      if(n != 0)
      {
#ifndef RLWIN32
        ::printf("rlSocket:tcp_connect error for %s port=%s : %s\n", adr, portstr, gai_strerror(n));
#endif
        return -1;
      }
      ressave = res;
      do
      {
        s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if(s < 0)                                            continue; // ignore this one
        if(::connect(s, res->ai_addr, res->ai_addrlen) == 0) break;    // success
        disconnect();                                                  // ignore this one
      }
      while((res = res->ai_next) != NULL);
      if(res == NULL) ::printf("rlSocket:tcp_connect error for %s port=%s\n", adr, portstr);
      freeaddrinfo(ressave);
#else
      ::printf("rlSocket:ERROR IPV6 not available on this platform\n");
#endif
    }
    else
    {
      ::printf("rlSocket:ERROR: rl_ipversion=%d not known\n", rl_ipversion);
    }
  }
  return s;
}