## modules/th/thread.c

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. TH_acquire_read_lock
2. TH_release_read_lock
3. TH_acquire_write_lock
4. TH_release_write_lock
5. TH_init_read_write_lock
6. TH_acquire_read_lockw
7. TH_release_read_lockw
8. TH_acquire_write_lockw
9. TH_release_write_lockw
10. TH_init_read_write_lockw
11. TH_get_id
12. TH_to_string
13. TH_create

       1 /***************************************
       2   $Revision: 1.26 $
       3
       4   Example code: A thread.
       5
       6   Status: NOT REVUED, NOT TESTED
       7
       8  Authors:       Chris Ottrey
       9                 Joao Damas
      10
      11   +html+ <DL COMPACT>
      12   +html+ <DT>Online References:
      13   +html+ <DD><UL>
      14   +html+ </UL>
      15   +html+ </DL>
      16
      17   ******************/ /******************
      18   Modification History:
      19         ottrey (02/03/1999) Created.
      20         ottrey (08/03/1999) Modified.
      21         ottrey (17/06/1999) Stripped down.
      22         joao   (22/06/1999) Redid thread startup
      23   ******************/ /******************
      24   Copyright (c) 1999                              RIPE NCC
      25
      26   All Rights Reserved
      27
      28   Permission to use, copy, modify, and distribute this software and its
      29   documentation for any purpose and without fee is hereby granted,
      30   provided that the above copyright notice appear in all copies and that
      31   both that copyright notice and this permission notice appear in
      32   supporting documentation, and that the name of the author not be
      33   used in advertising or publicity pertaining to distribution of the
      34   software without specific, written prior permission.
      35
      36   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
      37   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
      38   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
      39   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
      40   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      41   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      42   ***************************************/
      43 #include <pthread.h>       /* Posix thread library */
      44 #include <stdio.h>
      45 #include <strings.h>
      46
      47 #include "thread.h"
      48 /* #include "socket.h"
      49 #include "protocol_whois.h"
      50 #include "protocol_config.h"
      51 #include "protocol_mirror.h"
      52 #include "constants.h"
      53 #include "server.h"
      54 */
      55 #include "memwrap.h"
      56
      57
      58 /*+ String sizes +*/
      59 #define STR_S   63
      60 #define STR_M   255
      61 #define STR_L   1023
      62 #define STR_XL  4095
      63 #define STR_XXL 16383
      64
      65 //typedef struct th_args {
      66 //      void *function;
      67 //      int sock;
      68 //} th_args;
      69
      70 /*************************************************
      71 *                                                *
      72 *     Readers Writes Locks that favor READERS    *
      73 *                                                *
      74 *************************************************/
      75 /* TH_acquire_read_lock() */
      76 /*++++++++++++++++++++++++++++++++++++++
      77
      78   Aquire a readers lock.
      79
      80   rw_lock_t *prw_lock Readers writers lock.
      81
      82   Reference: "Multithreaded Programming Techniques - Prasad p.192"
      83   More:
      84   +html+ <PRE>
      85   Author:
      86         ottrey
      87   +html+ </PRE>
      88   ++++++++++++++++++++++++++++++++++++++*/
      89 void TH_acquire_read_lock(rw_lock_t *prw_lock) {
         /* [<][>][^][v][top][bottom][index][help] */
      90   pthread_mutex_lock(&prw_lock->rw_mutex);
      91
      92   while (prw_lock->rw_count < 0) {
      93     pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
      94   }
      95
      96   ++prw_lock->rw_count;
      97   pthread_mutex_unlock(&prw_lock->rw_mutex);
      98
      99 } /* TH_acquire_read_lock() */
     100
     101 /* TH_release_read_lock() */
     102 /*++++++++++++++++++++++++++++++++++++++
     103
     104   Release a readers lock.
     105
     106   rw_lock_t *prw_lock Readers writers lock.
     107
     108   Reference: "Multithreaded Programming Techniques - Prasad p.192"
     109   More:
     110   +html+ <PRE>
     111   Author:
     112         ottrey
     113   +html+ </PRE>
     114   ++++++++++++++++++++++++++++++++++++++*/
     115 void TH_release_read_lock(rw_lock_t *prw_lock) {
         /* [<][>][^][v][top][bottom][index][help] */
     116   pthread_mutex_lock(&prw_lock->rw_mutex);
     117
     118   --prw_lock->rw_count;
     119
     120   if (!prw_lock->rw_count) {
     121     pthread_cond_signal(&prw_lock->rw_cond);
     122   }
     123
     124   pthread_mutex_unlock(&prw_lock->rw_mutex);
     125
     126 } /* TH_release_read_lock() */
     127
     128 /* TH_acquire_write_lock() */
     129 /*++++++++++++++++++++++++++++++++++++++
     130
     131   Aquire a writers lock.
     132
     133   rw_lock_t *prw_lock Readers writers lock.
     134
     135   Reference: "Multithreaded Programming Techniques - Prasad p.192"
     136   More:
     137   +html+ <PRE>
     138   Author:
     139         ottrey
     140   +html+ </PRE>
     141   ++++++++++++++++++++++++++++++++++++++*/
     142 void TH_acquire_write_lock(rw_lock_t *prw_lock) {
         /* [<][>][^][v][top][bottom][index][help] */
     143   pthread_mutex_lock(&prw_lock->rw_mutex);
     144
     145   while (prw_lock->rw_count != 0) {
     146     pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
     147   }
     148
     149   prw_lock->rw_count = -1;
     150   pthread_mutex_unlock(&prw_lock->rw_mutex);
     151
     152 } /* TH_acquire_write_lock() */
     153
     154 /* TH_release_write_lock() */
     155 /*++++++++++++++++++++++++++++++++++++++
     156
     157   Release a writers lock.
     158
     159   rw_lock_t *prw_lock Readers writers lock.
     160
     161   Reference: "Multithreaded Programming Techniques - Prasad p.192"
     162   More:
     163   +html+ <PRE>
     164   Author:
     165         ottrey
     166   +html+ </PRE>
     167   ++++++++++++++++++++++++++++++++++++++*/
     168 void TH_release_write_lock(rw_lock_t *prw_lock) {
         /* [<][>][^][v][top][bottom][index][help] */
     169   pthread_mutex_lock(&prw_lock->rw_mutex);
     170   prw_lock->rw_count = 0;
     171   pthread_mutex_unlock(&prw_lock->rw_mutex);
     172   pthread_cond_broadcast(&prw_lock->rw_cond);
     173
     174 } /* TH_release_write_lock() */
     175
     176 /* TH_init_read_write_lock() */
     177 /*++++++++++++++++++++++++++++++++++++++
     178
     179   Initialize a readers/writers lock.
     180
     181   rw_lock_t *prw_lock Readers writers lock.
     182
     183   Side effect: the lock is set to open(?)
     184
     185   Reference: "Multithreaded Programming Techniques - Prasad p.192"
     186   More:
     187   +html+ <PRE>
     188   Author:
     189         ottrey
     190   +html+ </PRE>
     191   ++++++++++++++++++++++++++++++++++++++*/
     192 void TH_init_read_write_lock(rw_lock_t *prw_lock) {
         /* [<][>][^][v][top][bottom][index][help] */
     193   pthread_mutex_init(&prw_lock->rw_mutex, NULL);
     194   pthread_cond_init(&prw_lock->rw_cond, NULL);
     195   pthread_cond_init(&prw_lock->w_cond, NULL);
     196   prw_lock->rw_count = 0;
     197   prw_lock->w_count = 1; /* just in case one uses wrong interface */
     198
     199 } /* TH_init_read_write_lock() */
     200
     201 /*************************************************
     202 *                                                *
     203 *     Readers Writes Locks that favor WRITERS    *
     204 *                                                *
     205 *************************************************/
     206 /* TH_acquire_read_lockw() */
     207 /*++++++++++++++++++++++++++++++++++++++
     208
     209   Aquire a readers lock.
     210
     211   rw_lock_t *prw_lock Readers writers lock.
     212
     213   Reference: "Multithreaded Programming Techniques - Prasad p.192"
     214   More:
     215   +html+ <PRE>
     216   Author:
     217         ottrey
     218   +html+ </PRE>
     219   ++++++++++++++++++++++++++++++++++++++*/
     220 void TH_acquire_read_lockw(rw_lock_t *prw_lock) {
         /* [<][>][^][v][top][bottom][index][help] */
     221   pthread_mutex_lock(&prw_lock->rw_mutex);
     222
     223   while (prw_lock->w_count != 0) {
     224     pthread_cond_wait(&prw_lock->w_cond, &prw_lock->rw_mutex);
     225   }
     226
     227   ++prw_lock->rw_count;
     228   pthread_mutex_unlock(&prw_lock->rw_mutex);
     229
     230 } /* TH_acquire_read_lockw() */
     231
     232 /* TH_release_read_lockw() */
     233 /*++++++++++++++++++++++++++++++++++++++
     234
     235   Release a readers lock.
     236
     237   rw_lock_t *prw_lock Readers writers lock.
     238
     239   Reference: "Multithreaded Programming Techniques - Prasad p.192"
     240   More:
     241   +html+ <PRE>
     242   Author:
     243         ottrey
     244   +html+ </PRE>
     245   ++++++++++++++++++++++++++++++++++++++*/
     246 void TH_release_read_lockw(rw_lock_t *prw_lock) {
         /* [<][>][^][v][top][bottom][index][help] */
     247   pthread_mutex_lock(&prw_lock->rw_mutex);
     248
     249   --prw_lock->rw_count;
     250
     251   if (!prw_lock->rw_count) {
     252     pthread_cond_signal(&prw_lock->rw_cond);
     253   }
     254
     255   pthread_mutex_unlock(&prw_lock->rw_mutex);
     256
     257 } /* TH_release_read_lockw() */
     258
     259 /* TH_acquire_write_lockw() */
     260 /*++++++++++++++++++++++++++++++++++++++
     261
     262   Aquire a writers lock.
     263
     264   rw_lock_t *prw_lock Readers writers lock.
     265
     266   Reference: "Multithreaded Programming Techniques - Prasad p.192"
     267   More:
     268   +html+ <PRE>
     269   Author:
     270         ottrey
     271   +html+ </PRE>
     272   ++++++++++++++++++++++++++++++++++++++*/
     273 void TH_acquire_write_lockw(rw_lock_t *prw_lock) {
         /* [<][>][^][v][top][bottom][index][help] */
     274   pthread_mutex_lock(&prw_lock->rw_mutex);
     275
     276  /* check for writers */
     277   while (prw_lock->w_count != 0) {
     278     pthread_cond_wait(&prw_lock->w_cond, &prw_lock->rw_mutex);
     279   }
     280
     281   prw_lock->w_count = 1;
     282
     283  /* wait until all readers are gone */
     284   while (prw_lock->rw_count != 0) {
     285     pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
     286   }
     287
     288   pthread_mutex_unlock(&prw_lock->rw_mutex);
     289
     290 } /* TH_acquire_write_lockw() */
     291
     292 /* TH_release_write_lockw() */
     293 /*++++++++++++++++++++++++++++++++++++++
     294
     295   Release a writers lock.
     296
     297   rw_lock_t *prw_lock Readers writers lock.
     298
     299   Reference: "Multithreaded Programming Techniques - Prasad p.192"
     300   More:
     301   +html+ <PRE>
     302   Author:
     303         ottrey
     304   +html+ </PRE>
     305   ++++++++++++++++++++++++++++++++++++++*/
     306 void TH_release_write_lockw(rw_lock_t *prw_lock) {
         /* [<][>][^][v][top][bottom][index][help] */
     307   pthread_mutex_lock(&prw_lock->rw_mutex);
     308   prw_lock->w_count = 0;
     309   pthread_mutex_unlock(&prw_lock->rw_mutex);
     310   pthread_cond_broadcast(&prw_lock->w_cond);
     311
     312 } /* TH_release_write_lockw() */
     313
     314 /* TH_init_read_write_lockw() */
     315 /*++++++++++++++++++++++++++++++++++++++
     316
     317   Initialize a readers/writers lock.
     318
     319   rw_lock_t *prw_lock Readers writers lock.
     320
     321   Side effect: the lock is set to open(?)
     322
     323   Reference: "Multithreaded Programming Techniques - Prasad p.192"
     324   More:
     325   +html+ <PRE>
     326   Author:
     327         ottrey
     328   +html+ </PRE>
     329   ++++++++++++++++++++++++++++++++++++++*/
     330 void TH_init_read_write_lockw(rw_lock_t *prw_lock) {
         /* [<][>][^][v][top][bottom][index][help] */
     331   pthread_mutex_init(&prw_lock->rw_mutex, NULL);
     332   pthread_cond_init(&prw_lock->rw_cond, NULL);
     333   pthread_cond_init(&prw_lock->w_cond, NULL);
     334   prw_lock->rw_count = 0;
     335   prw_lock->w_count = 0;
     336
     337 } /* TH_init_read_write_lockw() */
     338
     339
     340
     341 /*************************************************
     342 *                                                *
     343 *     Other functions                            *
     344 *                                                *
     345 *************************************************/
     346
     347
     348 int TH_get_id(void) {
         /* [<][>][^][v][top][bottom][index][help] */
     349
     350   return (int)pthread_self();
     351
     352 } /* TH_get_id() */
     353
     354 /* TH_to_string() */
     355 char *TH_to_string(void) {
         /* [<][>][^][v][top][bottom][index][help] */
     356   char *thread_info;
     357   char tmp[STR_L];
     358   char thread_info_buffer[STR_XL];
     359
     360   strcpy(thread_info_buffer, "Thread = { ");
     361
     362   sprintf(tmp, "[pthread_self] = \"%d\" ", pthread_self());
     363   strcat(thread_info_buffer, tmp);
     364
     365   /*
     366   thread_name = (char *)pthread_getspecific(Name);
     367
     368   if (thread_name == NULL ) {
     369     sprintf(tmp, "[Name] = \"%s\" ", "didn't work!");
     370   }
     371   else {
     372     sprintf(tmp, "[Name] = \"%s\" ", thread_name);
     373   }
     374   strcat(thread_info_buffer, tmp);
     375   */
     376
     377   strcat(thread_info_buffer, "}");
     378
     379   dieif( wr_malloc((void **)&thread_info,
     380                    strlen(thread_info_buffer)+1) != UT_OK);
     381
     382   strcpy(thread_info, thread_info_buffer);
     383
     384   return thread_info;
     385 } /* TH_to_string() */
     386
     387
     388 /*++++++++++++++++++++++++++++++++++++++
     389
     390   This is the routine that creates a thread.
     391
     392    More:
     393   +html+ <PRE>
     394   Author:
     395         ottrey
     396         joao
     397         andrei
     398   +html+ </PRE>
     399   ++++++++++++++++++++++++++++++++++++++*/
     400 pthread_t TH_create(void *do_function(void *), void *arguments ) {
         /* [<][>][^][v][top][bottom][index][help] */
     401   pthread_t tid;
     402   pthread_attr_t attr;
     403   size_t ssize;
     404   int ret;
     405
     406     /* Start a new thread. */
     407     pthread_attr_init(&attr);     /* initialize attr with default attributes */
     408     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
     409
     410 #if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
     411     defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
     412     /*********
     413       For SCO, we need to increase the stack size, because the default is
     414       exceedingly small.  This also works on FreeBSD.  In Solaris, the
     415       stack size is 0, which is interpreted as the default, meaning 1
     416       Mbyte for 32-bit processes or 2 Mbyte for 64-bit processes.
     417       However, trying to *set* the stack size to 0 results in an error.
     418       Therefore, we don't want to set the size to 0.  Probably not a good
     419       idea in any event.  :) Linux doesn't support this function (as of
     420       the 2.4.2 kernel).
     421
     422       Note: see also modules/sk/cd_watchdog.c
     423      *********/
     424     dieif(pthread_attr_getstacksize(&attr, &ssize) != 0);
     425     if (ssize > 0) {
     426         dieif(pthread_attr_setstacksize(&attr, ssize * 4) != 0);
     427     }
     428 #endif
     429
     430     ret = pthread_create(&tid, &attr, do_function, arguments);
     431     if( ret !=0 ) die;
     432     pthread_attr_destroy(&attr);
     433
     434     return tid;
     435
     436 } /* TH_run() */
     437
     438
     439

/* [<][>][^][v][top][bottom][index][help] */