~vcs-imports/simias/trunk

« back to all changes in this revision

Viewing changes to simias/tools/gsoap/gsoap-linux-2.7/samples/magic/mtmagicserver.cpp

  • Committer: kalidasbala
  • Date: 2007-08-25 12:48:51 UTC
  • Revision ID: vcs-imports@canonical.com-20070825124851-vlfvzun3732ld196
Latest gsoap code update

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//      mtmagicserver.cpp
 
2
//      Multi-threaded magic squares server
 
3
//      Runs as CGI (not multi-threaded) or multi-threaded standalone
 
4
//      Computation of the magic square has been deliberately slowed down to
 
5
//      demonstrate work load issues (see SLEEP constant)
 
6
 
 
7
// Run from the command line with arguments IP (which must be the
 
8
// IP of the current machine you are using) and PORT to run this as a
 
9
// multi-threaded stand-alone server on a port. For example:
 
10
// > mtmagicserver.cgi 18081
 
11
// To let 'magic' client talk to this service, change the URL in code magic.cpp
 
12
// into "localhost:18081"
 
13
 
 
14
// This example illustrates two alternative server implementations with threads.
 
15
// The first implementation recycles gSOAP resources but is bounded to a maximum
 
16
// number of threads. Each thread needs to be joined, so runaway processes will
 
17
// halt the server at some point.
 
18
// The second implementation has no thread limitation. Runaway threads are not
 
19
// controlled.
 
20
 
 
21
#include "soapH.h"
 
22
#include "magic.nsmap"
 
23
#include <unistd.h>     // import sleep()
 
24
#include <pthread.h>
 
25
 
 
26
#define BACKLOG (100)   // Max. request backlog
 
27
#define MAX_THR (8)     // Max. threads to serve requests
 
28
#define SLEEP   (0)     // use this to make each thread sleep to mimic work load latency
 
29
 
 
30
////////////////////////////////////////////////////////////////////////////////
 
31
//
 
32
//      Multi-Threaded Magic Squares Server
 
33
//
 
34
////////////////////////////////////////////////////////////////////////////////
 
35
 
 
36
void *process_request(void*);
 
37
 
 
38
int main(int argc, char **argv)
 
39
{ struct soap soap;
 
40
  soap_init(&soap);
 
41
  // soap.accept_timeout = 60; // die if no requests are made within 1 minute
 
42
  if (argc < 2)         // no args: assume this is a CGI application
 
43
  { soap_serve(&soap);  // serve request
 
44
    soap_destroy(&soap);// cleanup class instances
 
45
    soap_end(&soap);    // cleanup
 
46
  }
 
47
  else
 
48
  { pthread_t tid;
 
49
    int port;
 
50
    int m, s, i;
 
51
    port = atoi(argv[1]);
 
52
    m = soap_bind(&soap, NULL, port, BACKLOG);
 
53
    if (m < 0)
 
54
    { soap_print_fault(&soap, stderr);
 
55
      exit(1);
 
56
    }
 
57
    fprintf(stderr, "Socket connection successful %d\n", m);
 
58
    for (i = 0; ; i++)
 
59
    { s = soap_accept(&soap);
 
60
      if (s < 0)
 
61
      { if (soap.errnum)
 
62
          soap_print_fault(&soap, stderr);
 
63
        else
 
64
          fprintf(stderr, "Server timed out\n");
 
65
        break;
 
66
      }
 
67
      fprintf(stderr, "Thread %d accepts socket %d connection from IP %d.%d.%d.%d\n", i, s, (int)(soap.ip>>24)&0xFF, (int)(soap.ip>>16)&0xFF, (int)(soap.ip>>8)&0xFF, (int)soap.ip&0xFF);
 
68
      pthread_create(&tid, NULL, (void*(*)(void*))process_request, (void*)soap_copy(&soap));
 
69
    }
 
70
  }
 
71
  soap_done(&soap);
 
72
  return 0;
 
73
}
 
74
 
 
75
void *process_request(void *soap)
 
76
{ pthread_detach(pthread_self());
 
77
  soap_serve((struct soap*)soap);
 
78
  soap_destroy((struct soap*)soap);
 
79
  soap_end((struct soap*)soap);
 
80
  soap_done((struct soap*)soap);
 
81
  free(soap);
 
82
  return NULL;
 
83
}
 
84
 
 
85
////////////////////////////////////////////////////////////////////////////////
 
86
//
 
87
//      Magic Square Algorithm
 
88
//
 
89
////////////////////////////////////////////////////////////////////////////////
 
90
 
 
91
int ns1__magic(struct soap *soap, int n, matrix *square)
 
92
{ int i, j, k, l, key = 2;
 
93
  if (n < 1)
 
94
    return soap_sender_fault(soap, "Negative or zero size", "<error xmlns=\"http://tempuri.org/\">The input parameter must be positive</error>");
 
95
  if (n > 100)
 
96
    return soap_sender_fault(soap, "size > 100", "<error xmlns=\"http://tempuri.org/\">The input parameter must not be too large</error>");
 
97
  square->resize(n, n);
 
98
  for (i = 0; i < n; i++)
 
99
    for (j = 0; j < n; j++)
 
100
      (*square)[i][j] = 0;
 
101
  i = 0;
 
102
  j = (n-1)/2;
 
103
  (*square)[i][j] = 1;
 
104
  while (key <= n*n)
 
105
  { if (i-1 < 0)
 
106
      k = n-1;
 
107
    else
 
108
      k = i-1;
 
109
    if (j-1 < 0)
 
110
      l = n-1;
 
111
    else
 
112
      l = j-1;
 
113
    if ((*square)[k][l])
 
114
      i = (i+1) % n;
 
115
    else
 
116
    { i = k;
 
117
      j = l;
 
118
    }
 
119
    (*square)[i][j] = key;
 
120
    key++;
 
121
  }
 
122
  sleep(SLEEP);         // mimic work load latency
 
123
  return SOAP_OK;
 
124
}
 
125
 
 
126
////////////////////////////////////////////////////////////////////////////////
 
127
//
 
128
//      Class vector Methods
 
129
//
 
130
////////////////////////////////////////////////////////////////////////////////
 
131
 
 
132
vector::vector()
 
133
{ __ptr = 0;
 
134
  __size = 0;
 
135
}
 
136
 
 
137
vector::vector(int n)
 
138
{ __ptr = (int*)soap_malloc(soap, n*sizeof(int));
 
139
  __size = n;
 
140
}
 
141
 
 
142
vector::~vector()
 
143
{ soap_unlink(soap, this); // not required, but just to make sure if someone calls delete on this
 
144
}
 
145
 
 
146
void vector::resize(int n)
 
147
{ int *p;
 
148
  if (__size == n)
 
149
    return;
 
150
  p = (int*)soap_malloc(soap, n*sizeof(int));
 
151
  if (__ptr)
 
152
  { for (int i = 0; i < (n <= __size ? n : __size); i++)
 
153
      p[i] = __ptr[i];
 
154
    soap_unlink(soap, __ptr);
 
155
    free(__ptr);
 
156
  }
 
157
  __size = n;
 
158
  __ptr = p;
 
159
}
 
160
 
 
161
int& vector::operator[](int i) const
 
162
{ if (!__ptr || i < 0 || i >= __size)
 
163
    fprintf(stderr, "Array index out of bounds\n");
 
164
  return __ptr[i];
 
165
}
 
166
 
 
167
////////////////////////////////////////////////////////////////////////////////
 
168
//
 
169
//      Class matrix Methods
 
170
//
 
171
////////////////////////////////////////////////////////////////////////////////
 
172
 
 
173
matrix::matrix()
 
174
{ __ptr = 0;
 
175
  __size = 0;
 
176
}
 
177
 
 
178
matrix::matrix(int rows, int cols)
 
179
{ __ptr = soap_new_vector(soap, rows);
 
180
  for (int i = 0; i < cols; i++)
 
181
    __ptr[i].resize(cols);
 
182
  __size = rows;
 
183
}
 
184
 
 
185
matrix::~matrix()
 
186
{ soap_unlink(soap, this); // not required, but just to make sure if someone calls delete on this
 
187
}
 
188
 
 
189
void matrix::resize(int rows, int cols)
 
190
{ int i;
 
191
  vector *p;
 
192
  if (__size != rows)
 
193
  { if (__ptr)
 
194
    { p = soap_new_vector(soap, rows);
 
195
      for (i = 0; i < (rows <= __size ? rows : __size); i++)
 
196
      { if (this[i].__size != cols)
 
197
          (*this)[i].resize(cols);
 
198
        (p+i)->__ptr = __ptr[i].__ptr;
 
199
        (p+i)->__size = cols;
 
200
      }
 
201
      for (; i < rows; i++)
 
202
        __ptr[i].resize(cols);
 
203
    }
 
204
    else
 
205
    { __ptr = soap_new_vector(soap, rows);
 
206
      for (i = 0; i < rows; i++)
 
207
        __ptr[i].resize(cols);
 
208
      __size = rows;
 
209
    }
 
210
  }
 
211
  else
 
212
    for (i = 0; i < __size; i++)
 
213
      __ptr[i].resize(cols);
 
214
}
 
215
 
 
216
vector& matrix::operator[](int i) const
 
217
{ if (!__ptr || i < 0 || i >= __size)
 
218
    fprintf(stderr, "Array index out of bounds\n");
 
219
  return __ptr[i];
 
220
}