File: win32_mtasker.hh

package info (click to toggle)
pdns-recursor 3.2-4+deb6u1
  • links: PTS
  • area: main
  • in suites: squeeze-lts
  • size: 1,220 kB
  • ctags: 2,721
  • sloc: cpp: 12,564; ansic: 2,587; sh: 510; makefile: 133
file content (113 lines) | stat: -rw-r--r-- 3,360 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
    PowerDNS Versatile Database Driven Nameserver
    Copyright (C) 2002  PowerDNS.COM BV

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#ifndef WIN32_MTASKER_HH
#define WIN32_MTASKER_HH

#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>

#include <queue>
#include <vector> 
#include <map>
#include <time.h>
#include <boost/multi_index_container.hpp>

struct KeyTag {};

//! The main MTasker class    
/** The main MTasker class. See the main page for more information.
    \param EventKey Type of the key with which events are to be identified. Defaults to int.
    \param EventVal Type of the content or value of an event. Defaults to int. Cannot be set to void.
    \note The EventKey needs to have an operator< defined because it is used as the key of an associative array
*/
template<class EventKey=int, class EventVal=int> class MTasker
{
public:
  struct Waiter
  {
    LPVOID context;
    time_t ttd;
    int tid;
    EventKey key;
  };
  typedef multi_index_container<
    Waiter,
    indexed_by <
                ordered_unique<member<Waiter,EventKey,&Waiter::key> >,
                ordered_non_unique<tag<KeyTag>, member<Waiter,time_t,&Waiter::ttd> >
               >
  > waiters_t;

  waiters_t d_waiters;

private:  
  LPVOID d_kernel;     
  std::queue<int> d_runQueue;
  std::queue<int> d_zombiesQueue;


  std::map<int,LPVOID> d_threads;
  int d_tid;
  int d_maxtid;
  size_t d_stacksize;

  EventVal d_waitval;
  EventKey d_eventkey;
  enum {Error=-1,TimeOut=0,Answer} d_waitstatus;

public:
  //! Constructor
  /** Constructor with a small default stacksize. If any of your threads exceeds this stack, your application will crash. 
      This limit applies solely to the stack, the heap is not limited in any way. If threads need to allocate a lot of data,
      the use of new/delete is suggested. 
   */
  MTasker(size_t stacksize=8192) : d_stacksize(stacksize)
  {
    d_kernel=ConvertThreadToFiber( NULL );
    d_maxtid=0;
  }

  typedef void tfunc_t(void *); //!< type of the pointer that starts a thread 
  int waitEvent(EventKey &key, EventVal *val=0, unsigned int timeout=0);
  void yield();
  int sendEvent(const EventKey& key, const EventVal* val=0);
  void getEvents(std::vector<EventKey>& events);
  void makeThread(tfunc_t *start, void* val);
  bool schedule();
  bool noProcesses();
  unsigned int numProcesses();
  int getTid(); 

private:
  //! This structure holds some fiber data that is passed to the threadWrapper.
  struct ThreadParam
  {
    tfunc_t *tf; 
    MTasker *self; 
    int tid; 
    LPVOID val; 
  };
 
  static void WINAPI threadWrapper( LPVOID lpFiberParameter );
};

#include "win32_mtasker.cc"

#endif // WIN32_MTASKER_HH