~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to iocore/eventsystem/P_UnixSocketManager.h

  • Committer: Bazaar Package Importer
  • Author(s): Arno Toell
  • Date: 2011-01-13 11:49:18 UTC
  • Revision ID: james.westby@ubuntu.com-20110113114918-vu422h8dknrgkj15
Tags: upstream-2.1.5-unstable
ImportĀ upstreamĀ versionĀ 2.1.5-unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 
 
3
  A brief file description
 
4
 
 
5
  @section license License
 
6
 
 
7
  Licensed to the Apache Software Foundation (ASF) under one
 
8
  or more contributor license agreements.  See the NOTICE file
 
9
  distributed with this work for additional information
 
10
  regarding copyright ownership.  The ASF licenses this file
 
11
  to you under the Apache License, Version 2.0 (the
 
12
  "License"); you may not use this file except in compliance
 
13
  with the License.  You may obtain a copy of the License at
 
14
 
 
15
      http://www.apache.org/licenses/LICENSE-2.0
 
16
 
 
17
  Unless required by applicable law or agreed to in writing, software
 
18
  distributed under the License is distributed on an "AS IS" BASIS,
 
19
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
20
  See the License for the specific language governing permissions and
 
21
  limitations under the License.
 
22
 */
 
23
 
 
24
/****************************************************************************
 
25
 
 
26
  UnixSocketManager.h
 
27
 
 
28
  Handle the allocation of the socket descriptor (fd) resource.
 
29
 
 
30
 
 
31
****************************************************************************/
 
32
#ifndef _P_UnixSocketManager_h_
 
33
#define _P_UnixSocketManager_h_
 
34
 
 
35
#include "libts.h"
 
36
#include "I_SocketManager.h"
 
37
 
 
38
 
 
39
//
 
40
// These limits are currently disabled
 
41
//
 
42
// 1024 - stdin, stderr, stdout
 
43
#define EPOLL_MAX_DESCRIPTOR_SIZE                32768
 
44
 
 
45
TS_INLINE bool
 
46
transient_error()
 
47
{
 
48
  bool transient = (errno == EINTR);
 
49
#ifdef ENOMEM
 
50
  transient = transient || (errno == ENOMEM);
 
51
#endif
 
52
#ifdef ENOBUFS
 
53
  transient = transient || (errno == ENOBUFS);
 
54
#endif
 
55
  return transient;
 
56
}
 
57
 
 
58
 
 
59
//
 
60
// Timing done in the connectionManager
 
61
//
 
62
TS_INLINE int
 
63
SocketManager::accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 
64
{
 
65
  int r;
 
66
  do {
 
67
    r =::accept(s, addr, addrlen);
 
68
    if (likely(r >= 0))
 
69
      break;
 
70
    r = -errno;
 
71
  } while (transient_error());
 
72
 
 
73
  return r;
 
74
}
 
75
 
 
76
TS_INLINE int
 
77
SocketManager::open(const char *path, int oflag, mode_t mode)
 
78
{
 
79
  int s;
 
80
  do {
 
81
    s =::open(path, oflag, mode);
 
82
    if (likely(s >= 0))
 
83
      break;
 
84
    s = -errno;
 
85
  } while (transient_error());
 
86
  return s;
 
87
}
 
88
 
 
89
TS_INLINE int64_t
 
90
SocketManager::read(int fd, void *buf, int size, void *pOLP)
 
91
{
 
92
  NOWARN_UNUSED(pOLP);
 
93
  int64_t r;
 
94
  do {
 
95
    r =::read(fd, buf, size);
 
96
    if (likely(r >= 0))
 
97
      break;
 
98
    r = -errno;
 
99
  } while (r == -EINTR);
 
100
  return r;
 
101
}
 
102
 
 
103
TS_INLINE int64_t
 
104
SocketManager::pread(int fd, void *buf, int size, off_t offset, char *tag)
 
105
{
 
106
  NOWARN_UNUSED(tag);
 
107
  int64_t r;
 
108
  do {
 
109
    r =::pread(fd, buf, size, offset);
 
110
    if (r < 0)
 
111
      r = -errno;
 
112
  } while (r == -EINTR);
 
113
  return r;
 
114
}
 
115
 
 
116
TS_INLINE int64_t
 
117
SocketManager::readv(int fd, struct iovec *vector, size_t count)
 
118
{
 
119
  int64_t r;
 
120
  do {
 
121
    // coverity[tainted_data_argument]
 
122
    if (likely((r =::readv(fd, vector, count)) >= 0))
 
123
      break;
 
124
    r = -errno;
 
125
  } while (transient_error());
 
126
  return r;
 
127
}
 
128
 
 
129
TS_INLINE int64_t
 
130
SocketManager::vector_io(int fd, struct iovec *vector, size_t count, int read_request, void *pOLP)
 
131
{
 
132
  NOWARN_UNUSED(pOLP);
 
133
  const int max_iovecs_per_request = 16;
 
134
  int n;
 
135
  int64_t r = 0;
 
136
  int n_vec;
 
137
  int64_t bytes_xfered = 0;
 
138
  int current_count;
 
139
  int64_t current_request_bytes;
 
140
 
 
141
  for (n_vec = 0; n_vec < (int) count; n_vec += max_iovecs_per_request) {
 
142
    current_count = min(max_iovecs_per_request, ((int) (count - n_vec)));
 
143
    do {
 
144
      // coverity[tainted_data_argument]
 
145
      r = read_request ? ::readv(fd, &vector[n_vec], current_count) : ::writev(fd, &vector[n_vec], current_count);
 
146
      if (likely(r >= 0))
 
147
        break;
 
148
      r = -errno;
 
149
    } while (transient_error());
 
150
 
 
151
    if (r <= 0) {
 
152
      return (bytes_xfered && (r == -EAGAIN)) ? bytes_xfered : r;
 
153
    }
 
154
    bytes_xfered += r;
 
155
 
 
156
    if ((n_vec + max_iovecs_per_request) >= (int) count)
 
157
      break;
 
158
 
 
159
    // Compute bytes in current vector
 
160
    current_request_bytes = 0;
 
161
    for (n = n_vec; n < (n_vec + current_count); ++n)
 
162
      current_request_bytes += vector[n].iov_len;
 
163
 
 
164
    // Exit if we were unable to read all data in the current vector
 
165
    if (r != current_request_bytes)
 
166
      break;
 
167
  }
 
168
  return bytes_xfered;
 
169
}
 
170
 
 
171
TS_INLINE int64_t
 
172
SocketManager::read_vector(int fd, struct iovec *vector, size_t count, void *pOLP)
 
173
{
 
174
  return vector_io(fd, vector, count, 1, pOLP);
 
175
}
 
176
 
 
177
TS_INLINE int
 
178
SocketManager::recv(int fd, void *buf, int size, int flags)
 
179
{
 
180
  int r;
 
181
  do {
 
182
    if (unlikely((r =::recv(fd, (char *) buf, size, flags)) < 0)) {
 
183
      r = -errno;
 
184
    }
 
185
  } while (r == -EINTR);
 
186
  return r;
 
187
}
 
188
 
 
189
TS_INLINE int
 
190
SocketManager::recvfrom(int fd, void *buf, int size, int flags, struct sockaddr *addr, socklen_t *addrlen)
 
191
{
 
192
  int r;
 
193
  do {
 
194
    r =::recvfrom(fd, (char *) buf, size, flags, addr, addrlen);
 
195
    if (unlikely(r < 0))
 
196
      r = -errno;
 
197
  } while (r == -EINTR);
 
198
  return r;
 
199
}
 
200
 
 
201
TS_INLINE int64_t
 
202
SocketManager::write(int fd, void *buf, int size, void *pOLP)
 
203
{
 
204
  NOWARN_UNUSED(pOLP);
 
205
  int64_t r;
 
206
  do {
 
207
    if (likely((r =::write(fd, buf, size)) >= 0))
 
208
      break;
 
209
    r = -errno;
 
210
  } while (r == -EINTR);
 
211
  return r;
 
212
}
 
213
 
 
214
TS_INLINE int64_t
 
215
SocketManager::pwrite(int fd, void *buf, int size, off_t offset, char *tag)
 
216
{
 
217
  NOWARN_UNUSED(tag);
 
218
  int64_t r;
 
219
  do {
 
220
    if (unlikely((r =::pwrite(fd, buf, size, offset)) < 0))
 
221
      r = -errno;
 
222
  } while (r == -EINTR);
 
223
  return r;
 
224
}
 
225
 
 
226
TS_INLINE int64_t
 
227
SocketManager::writev(int fd, struct iovec *vector, size_t count)
 
228
{
 
229
  int64_t r;
 
230
  do {
 
231
    if (likely((r =::writev(fd, vector, count)) >= 0))
 
232
      break;
 
233
    r = -errno;
 
234
  } while (transient_error());
 
235
  return r;
 
236
}
 
237
 
 
238
TS_INLINE int64_t
 
239
SocketManager::write_vector(int fd, struct iovec *vector, size_t count, void *pOLP)
 
240
{
 
241
  return vector_io(fd, vector, count, 0, pOLP);
 
242
}
 
243
 
 
244
 
 
245
TS_INLINE int
 
246
SocketManager::send(int fd, void *buf, int size, int flags)
 
247
{
 
248
  int r;
 
249
  do {
 
250
    if (unlikely((r =::send(fd, (char *) buf, size, flags)) < 0))
 
251
      r = -errno;
 
252
  } while (r == -EINTR);
 
253
  return r;
 
254
}
 
255
 
 
256
TS_INLINE int
 
257
SocketManager::sendto(int fd, void *buf, int len, int flags, struct sockaddr *to, int tolen)
 
258
{
 
259
  int r;
 
260
  do {
 
261
    if (unlikely((r =::sendto(fd, (char *) buf, len, flags, to, tolen)) < 0))
 
262
      r = -errno;
 
263
  } while (r == -EINTR);
 
264
  return r;
 
265
}
 
266
 
 
267
TS_INLINE int
 
268
SocketManager::sendmsg(int fd, struct msghdr *m, int flags, void *pOLP)
 
269
{
 
270
  NOWARN_UNUSED(pOLP);
 
271
  int r;
 
272
  do {
 
273
    if (unlikely((r =::sendmsg(fd, m, flags)) < 0))
 
274
      r = -errno;
 
275
  } while (r == -EINTR);
 
276
  return r;
 
277
}
 
278
 
 
279
TS_INLINE int64_t
 
280
SocketManager::lseek(int fd, off_t offset, int whence)
 
281
{
 
282
  int64_t r;
 
283
  do {
 
284
    if ((r =::lseek(fd, offset, whence)) < 0)
 
285
      r = -errno;
 
286
  } while (r == -EINTR);
 
287
  return r;
 
288
}
 
289
 
 
290
TS_INLINE int
 
291
SocketManager::fstat(int fd, struct stat *buf)
 
292
{
 
293
  int r;
 
294
  do {
 
295
    if ((r =::fstat(fd, buf)) >= 0)
 
296
      break;
 
297
    r = -errno;
 
298
  } while (transient_error());
 
299
  return r;
 
300
}
 
301
 
 
302
TS_INLINE int
 
303
SocketManager::unlink(char *buf)
 
304
{
 
305
  int r;
 
306
  do {
 
307
    if ((r =::unlink(buf)) < 0)
 
308
      r = -errno;
 
309
  } while (r == -EINTR);
 
310
  return r;
 
311
}
 
312
 
 
313
TS_INLINE int
 
314
SocketManager::fsync(int fildes)
 
315
{
 
316
  int r;
 
317
  do {
 
318
    if ((r =::fsync(fildes)) < 0)
 
319
      r = -errno;
 
320
  } while (r == -EINTR);
 
321
  return r;
 
322
}
 
323
 
 
324
TS_INLINE int
 
325
SocketManager::ftruncate(int fildes, off_t length)
 
326
{
 
327
  int r;
 
328
  do {
 
329
    if ((r =::ftruncate(fildes, length)) < 0)
 
330
      r = -errno;
 
331
  } while (r == -EINTR);
 
332
  return r;
 
333
}
 
334
 
 
335
TS_INLINE int
 
336
SocketManager::poll(struct pollfd *fds, unsigned long nfds, int timeout)
 
337
{
 
338
  int r;
 
339
  do {
 
340
    if ((r =::poll(fds, nfds, timeout)) >= 0)
 
341
      break;
 
342
    r = -errno;
 
343
  } while (transient_error());
 
344
  return r;
 
345
}
 
346
 
 
347
#if TS_USE_EPOLL
 
348
TS_INLINE int
 
349
SocketManager::epoll_create(int size)
 
350
{
 
351
  int r;
 
352
  if (size <= 0)
 
353
    size = EPOLL_MAX_DESCRIPTOR_SIZE;
 
354
  do {
 
355
    if (likely((r =::epoll_create(size)) >= 0))
 
356
      break;
 
357
    r = -errno;
 
358
  } while (errno == -EINTR);
 
359
  return r;
 
360
}
 
361
 
 
362
TS_INLINE int
 
363
SocketManager::epoll_close(int epfd)
 
364
{
 
365
  int r = 0;
 
366
  if (likely(epfd >= 0)) {
 
367
    do {
 
368
      if (likely((r =::close(epfd)) == 0))
 
369
        break;
 
370
      r = -errno;
 
371
    } while (errno == -EINTR);
 
372
  }
 
373
  return r;
 
374
}
 
375
 
 
376
TS_INLINE int
 
377
SocketManager::epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
 
378
{
 
379
  int r;
 
380
  do {
 
381
    if (likely((r =::epoll_ctl(epfd, op, fd, event)) == 0))
 
382
      break;
 
383
    r = -errno;
 
384
  } while (errno == -EINTR);
 
385
  return r;
 
386
}
 
387
 
 
388
TS_INLINE int
 
389
SocketManager::epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
 
390
{
 
391
  int r;
 
392
  do {
 
393
    if ((r =::epoll_wait(epfd, events, maxevents, timeout)) >= 0)
 
394
      break;
 
395
    r = -errno;
 
396
  } while (errno == -EINTR);
 
397
  return r;
 
398
}
 
399
 
 
400
#endif /* TS_USE_EPOLL */
 
401
 
 
402
#if TS_USE_KQUEUE
 
403
TS_INLINE int
 
404
SocketManager::kqueue()
 
405
{
 
406
  return ::kqueue();
 
407
}
 
408
 
 
409
TS_INLINE int
 
410
SocketManager::kevent(int kq, const struct kevent *changelist, int nchanges,
 
411
                      struct kevent *eventlist, int nevents,
 
412
                      const struct timespec *timeout)
 
413
{
 
414
  int r;
 
415
  do {
 
416
    r =::kevent(kq, changelist, nchanges,
 
417
                eventlist, nevents, timeout);
 
418
    if (likely(r >= 0)) {
 
419
        break;
 
420
    }
 
421
    r = -errno;
 
422
  } while (errno == -EINTR);
 
423
  return r;
 
424
}
 
425
#endif /* TS_USE_KQUEUE */
 
426
 
 
427
#if TS_USE_PORT
 
428
TS_INLINE int
 
429
SocketManager::port_create()
 
430
{
 
431
  return ::port_create();
 
432
}
 
433
 
 
434
TS_INLINE int
 
435
SocketManager::port_associate(int port, int source, uintptr_t obj,
 
436
                              int events, void *user)
 
437
{
 
438
  int r;
 
439
  r =::port_associate(port, source, obj, events, user);
 
440
  if(r < 0)
 
441
    r = -errno;
 
442
  return r;
 
443
}
 
444
 
 
445
TS_INLINE int
 
446
SocketManager::port_dissociate(int port, int source, uintptr_t obj)
 
447
{
 
448
  int r;
 
449
  r =::port_dissociate(port, source, obj);
 
450
  if(r < 0)
 
451
    r = -errno;
 
452
  return r;
 
453
}
 
454
 
 
455
TS_INLINE int
 
456
SocketManager::port_getn(int port, port_event_t *list, uint_t max,
 
457
                         uint_t *nget, timespec_t *timeout)
 
458
{
 
459
  int r;
 
460
  do {
 
461
    if ((r =::port_getn(port, list, max, nget, timeout)) >= 0)
 
462
      break;
 
463
    r = -errno;
 
464
  } while (errno == -EINTR); //TODO: possible EAGAIN(undocumented)
 
465
  return r;
 
466
}
 
467
#endif /* TS_USE_PORT */
 
468
 
 
469
 
 
470
TS_INLINE int
 
471
SocketManager::get_sndbuf_size(int s)
 
472
{
 
473
  int bsz = 0;
 
474
  int bszsz, r;
 
475
 
 
476
  bszsz = sizeof(bsz);
 
477
  r = safe_getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &bsz, &bszsz);
 
478
  return (r == 0 ? bsz : r);
 
479
}
 
480
 
 
481
TS_INLINE int
 
482
SocketManager::get_rcvbuf_size(int s)
 
483
{
 
484
  int bsz = 0;
 
485
  int bszsz, r;
 
486
 
 
487
  bszsz = sizeof(bsz);
 
488
  r = safe_getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &bsz, &bszsz);
 
489
  return (r == 0 ? bsz : r);
 
490
}
 
491
 
 
492
TS_INLINE int
 
493
SocketManager::set_sndbuf_size(int s, int bsz)
 
494
{
 
495
  return safe_setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &bsz, sizeof(bsz));
 
496
}
 
497
 
 
498
TS_INLINE int
 
499
SocketManager::set_rcvbuf_size(int s, int bsz)
 
500
{
 
501
  return safe_setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &bsz, sizeof(bsz));
 
502
}
 
503
 
 
504
TS_INLINE int
 
505
SocketManager::getsockname(int s, struct sockaddr *sa, socklen_t *sz)
 
506
{
 
507
  return::getsockname(s, sa, sz);
 
508
}
 
509
 
 
510
TS_INLINE int
 
511
SocketManager::socket(int domain, int type, int protocol, bool bNonBlocking)
 
512
{
 
513
  NOWARN_UNUSED(bNonBlocking);
 
514
  return::socket(domain, type, protocol);
 
515
}
 
516
 
 
517
TS_INLINE int
 
518
SocketManager::mc_socket(int domain, int type, int protocol, bool bNonBlocking)
 
519
{
 
520
  return SocketManager::socket(domain, type, protocol, bNonBlocking);
 
521
}
 
522
 
 
523
TS_INLINE int
 
524
SocketManager::shutdown(int s, int how)
 
525
{
 
526
  int res;
 
527
  do {
 
528
    if (unlikely((res =::shutdown(s, how)) < 0))
 
529
      res = -errno;
 
530
  } while (res == -EINTR);
 
531
  return res;
 
532
}
 
533
 
 
534
TS_INLINE int
 
535
SocketManager::lockf(int s, int f, off_t size)
 
536
{
 
537
  int res;
 
538
  do {
 
539
    if ((res =::lockf(s, f, size)) < 0)
 
540
      res = -errno;
 
541
  } while (res == -EINTR);
 
542
  return res;
 
543
}
 
544
 
 
545
TS_INLINE int
 
546
SocketManager::dup(int s)
 
547
{
 
548
  int res;
 
549
  do {
 
550
    if ((res =::dup(s)) >= 0)
 
551
      break;
 
552
    res = -errno;
 
553
  } while (res == -EINTR);
 
554
  return res;
 
555
}
 
556
 
 
557
int safe_msync(caddr_t addr, size_t len, caddr_t end, int flags);
 
558
 
 
559
#ifndef MADV_NORMAL
 
560
#define MADV_NORMAL 0
 
561
#endif
 
562
 
 
563
#ifndef MADV_RANDOM
 
564
#define MADV_RANDOM 1
 
565
#endif
 
566
 
 
567
#ifndef MADV_SEQUENTIAL
 
568
#define MADV_SEQUENTIAL 2
 
569
#endif
 
570
 
 
571
#ifndef MADV_WILLNEED
 
572
#define MADV_WILLNEED 3
 
573
#endif
 
574
 
 
575
#ifndef MADV_DONTNEED
 
576
#define MADV_DONTNEED 4
 
577
#endif
 
578
 
 
579
int safe_madvise(caddr_t addr, size_t len, caddr_t end, int flags);
 
580
int safe_mlock(caddr_t addr, size_t len, caddr_t end);
 
581
 
 
582
#endif /*P_UnixSocketManager_h_ */